Yii 1.1: eclientscript

Extended clientscript to combine script and css files automatically
32 followers

Requirements

Yii 1.1.x or above

Description:

EClientScript (an extension for Yii's CClientScript)

This is an optimizing client script manager for Yii framework, that can minify and combine CSS/JS files.

It will automatically detects changes in file content (based on modification time) and generates a unique file name accordingly.

This will reduce the HTTP calls for resources files by merging several resources filesinto a single (or more) files.

Since version of 1.5, also support conditional loading js/css file in IE browser, see example codes please.

The source code is hosted under github:

https://github.com/muayyad-alsadi/yii-EClientScript

Css Files:

CSS files are merged based on there media attribute, background images with a relative path in file can also be displayed correctly.

Script files:

Script files are merged based on their position, If you use the 'CClientScript::POS_HEAD' you will end up with a single file for all the script files you've used on that page.

If you use 'CClientScript::POS_HEAD' and 'CClientScript::POS_END' for example then you'll end up with two files for each page on that request, becuase those resources are located in different positions.

File optmization (EXPERIMENTAL, @since: 1.1)

CssMin used to optimize merged css file. You can set property 'optmizeCssFiles' of the component to enable this feature. JSMinPlus used to optimize merged script file. You can set property 'optmizeScriptFiles' of the component to enable this feature.

Usage:

  1. Using this extension is as simple as adding the following code to the application configuration under the components array:

    'clientScript' => array(
       'class' => 'application.vendors.yii-EClientScript.EClientScript',
       'combineScriptFiles' => !YII_DEBUG, // By default this is set to true, set this to true if you'd like to combine the script files
       'combineCssFiles' => !YII_DEBUG, // By default this is set to true, set this to true if you'd like to combine the css files
       'optimizeScriptFiles' => !YII_DEBUG, // @since: 1.1
       'optimizeCssFiles' => !YII_DEBUG, // @since: 1.1
       'optimizeInlineScript' => false, // @since: 1.6, This may case response slower
       'optimizeInlineCss' => false, // @since: 1.6, This may case response slower
     ),

    Then you can use the regular 'registerScriptFile' & 'registerCssFile' methods as normal and the files will be combined or optimized automatically.

  2. Using to conditional loading js/css file for IE browser, you just need to specify the media property.

$cs = Yii::app()->clientScript;
 
// result to: <!--[if lt IE 9]><script src="/js/html5.js"></script><![endif]-->
$cs->registerScriptFile('/js/html5.js', CClientScript::POS_HEAD, array('media' => 'lt IE 9'));
 
// result to: <!--[if lte IE 6]><link rel="stylesheet" type="text/css" href="bootstrap/css/ie.css" /><![endif]-->
$cs->registerCssFile('/css/ie.css', 'lte IE 6');

NOTE:

If you registered some external resource files that not in the web application root directory, they will be kept and not combined. Compression or optmization is a EXPERIMENTAL feature, please use it carefully(@since: 1.1)

ChangesLog:

Aug 13, 2013

  • New version number 1.6
  • Fixed bug for merging minified scripts, they may be missing a semicolon at the end
  • Add support to optimize inline css/js codes

Aug 2, 2013

  • Fixed load order of non-combined css files.

Mar 29, 2013

  • New version number 1.5
  • Compatiable with the 3rd parameter of registerScript and registerScriptFile
  • Add support for conditional loading js/css file in IE.
  • Prepend the base url of current request when register a script/css file with relative path

Mar 27, 2013 (by Muayyad Alsadi)

  • New version number 1.4
  • update JSMinPlus, CssMin
  • use stronger hash for file names
  • consider modification time for calculating hash
  • enable all features by default

Dec 06, 2010

  • Fixed problem for css files that begin with @charset "xxx", it should be in the first line of file and not repeatly.
  • Add support for theme resource files.

Nov 23, 2010

  • Skip the minimization of files whose names include .pack.
  • Add the last modification time as the QUERY_STRING to merged file, to avoid not properly flush the browser cache when the file updated.

Nov 6, 2010

  • New version number 1.3
  • Not repeat the minimization of Javascript codes those who have been minimized, whose names include .min.
  • Fixed getRelativeUrl() platform compatibility issue. (thanks to Troto)

Known Issues:

When some resource files can not be merged and they are strictly dependent on loading order, then may have some problems.

Reporting Issue:

Reporting Issues and comments are welcome, please report issues to https://github.com/muayyad-alsadi/yii-EClientScript/issues

Total 17 comments

#15920 report it
Deele at 2013/12/29 12:58pm
Error in CssMin.php

My PHP Storm reports an error:

// CssMin.php
// class CssAtImportParserPlugin extends aCssParserPlugin {
// public function parse($index, $char, $previousChar, $state) {
$this->parser->buffer // Member has private access
#15292 report it
muayyad alsadi at 2013/10/24 06:52am
bug fixed

@Szincsák András: this bug is fixed here https://github.com/muayyad-alsadi/yii-EClientScript/commit/a097d8c

#15287 report it
Szincsák András at 2013/10/23 05:32pm
Extension is Great! There is an Important issue!!!

In the version 1.6 EClientScript.php registerCssFile and registerScript do not have return value !!!

If You use an EClientScript in the following way:

$cs=Yii::app()->clientScript;
        $cs->registerCssFile($path . '/content.css')
           ->registerScriptFile($path . '/jquery.cookie.js')

It causes a strong headache (like to me)!!!

Please change in source in line 115 (and similar in 132):

parent::registerCssFile($url, $media);

to

return parent::registerCssFile($url, $media);
#14713 report it
bbunlock at 2013/09/05 07:41am
creates new files each page load?

Hi I have been using your extension for a little while now and all seemed fine until I ran out of web space yesterday. I only use the "'combineCssFiles' => true" and all others false as it was breaking some things.

however it turns out that the script is creating a brand new version of the compbined css on every single page load/refresh, it isnt caching at all, after 3 months I had used up all my web space (30 gig) and thats because there was 29 gig of combined css files in the assets folder.

I have the extension in the protected/extension folder and I have the following added to my main.php config file

'clientScript' => array(
        'class' => 'ext.minify.EClientScript',
    'combineScriptFiles' => false, // By default this is set to true, set this to true if you'd like to combine the script files
    'combineCssFiles' => true, // By default this is set to true, set this to true if you'd like to combine the css files
    'optimizeScriptFiles' => false, // @since: 1.1
    'optimizeCssFiles' => false, // @since: 1.1
    'optimizeInlineScript' => false, // @since: 1.6, This may case response slower
    'optimizeInlineCss' => false, // @since: 1.6, This may case response slower
    'coreScriptPosition' => CClientScript::POS_END,
    'defaultScriptPosition' => CClientScript::POS_END,
    'defaultScriptFilePosition' => CClientScript::POS_END,
        ),

can you suggest why it is creating a new combined css every time?

regards

wayne

#14467 report it
hightman at 2013/08/13 10:40pm
=> muayyad alsadi

OK, thanks, I will change the extension README file later.

#14459 report it
muayyad alsadi at 2013/08/13 09:04am
moving to github

=>hightman can we use github https://github.com/muayyad-alsadi/yii-EClientScript it's better to keep track of each other's changes

I have more enhancements to do (we can pull from each other)

#12567 report it
hightman at 2013/03/29 03:56am
=> muayyad alsadi

Thanks you, I manually integrate your updating, and release new version 1.5

#12535 report it
muayyad alsadi at 2013/03/27 06:58am
updated and enhanced version

I've made a fork of your code on github and released v1.4

https://github.com/muayyad-alsadi/yii-EClientScript

the new version got updated minification and use mtime to generate file name

#5050 report it
redguy at 2011/09/10 06:58am
problem with js libraries depending on js location

There are number of libraries which depends on js file location to fetch other resources relatively. Common example is CKEditor which loads css, images, and other files relatively to 'ckeditor.js' location. When you merge this js to one file with others - CKEditor won't work.

My solution (I did such modyfication to make it work and use combined js feature):

provide 'public $whiteList = array()' configuration attribute in your component, and change piece of code that decides wheter to merge css/js entry or not. I have changed getLocalFile function to getLocalFileNotWhitelisted with body like this:

private function getLocalPathNotWhitelisted($url)
        {
                $basePath = dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR;
                $baseUrl = Yii::app()->request->baseUrl . '/';
                if (!strncmp($url, $baseUrl, strlen($baseUrl)))
                {
                        $fname = basename( $url );
                        if( in_array( $fname, $this->whiteList ) ) {
                                return false;
                        }
                        $url = $basePath . substr($url, strlen($baseUrl));
                        return $url;
                }
                return false;
        }

the core change to the original function is:

$fname = basename( $url );
if( in_array( $fname, $this->whiteList ) ) {
     return false;
}

This solutions makes it easy to specify which files cannot be merged with others.

#2878 report it
rickywu at 2011/02/21 02:20am
bug report

Can you keep the original order of the files that combined or not into one single file? In addition, if you choose some combination, some do not mix, it is difficult to do all in order to keep the original, so that it will generate an error, for example, CSS class application.

#2404 report it
phpdevmd at 2010/12/24 05:58am
Thank you

Works great on Yii-1.0.12

#2361 report it
augustin at 2010/12/16 08:52pm
svn?

svn address is ... ?

#2118 report it
hightman at 2010/11/13 09:41pm
=>nayjest

Have you resoloved this problem, I guess there may be bug for cssMin or jsMin library, try to disable 'optimizeCssFiles' ?

#2082 report it
Nayjest at 2010/11/09 07:55am
Error when merging CSS

Fatal error: Maximum execution time of 300 seconds exceeded in Z:\home\taft.loc\www\protected\extensions\minify\EClientScript.php on line 316

#2061 report it
hightman at 2010/11/06 09:20am
to nayjest
  1. Of course, only recombine files when they contain the files that last modification time newer than the combined file.
  2. Now the attribute variable CClientScript::$css and CClientScript::$scripts can be accessed in extended class, but there are not suitable naming scheme of these codes.
#2056 report it
Nayjest at 2010/11/05 07:04am
Awesome!

Great extension! It would be nice to add some caching and recombine files only when last modification date of files changes.

  • How about posibility to write scripts/css, defined via registerScript/registerCss to files & use corresponding links instead of script/css code? I think, it would be great!
#2029 report it
Troto at 2010/11/03 08:04am
all platforms compatible

line 314 (from v1.2) should be:

else if ($from === dirname($from))

Leave a comment

Please to leave your comment.

Create extension