Tuesday, June 26, 2012

Handling Scripts and CSS in Yii Framework

Handling Scripts and CSS in Yii Framework

Yii provide CClientScript to manage the scripts and css files in Yii.

Registering Core scripts that comes with Yii

To register the core jquery library that comes with yii, use the following methods.

Yii::app()->clientScript->registerCoreScript('jquery');
Yii::app()->clientScript->registerCoreScript( 'jquery.ui' );
//We need to pre-render the jquery.yiiactiveform.js on the view where we are going to place the AJAX functionality
Yii::app()->clientScript->registerCoreScript('yiiactiveform');

The above statement register the Jquery library and jquery ui, if YII_DEBUG is false then yii will register minimized version of Jquery & Jquery UI library.

To register inline scripts and css files
Yii::app()->clientScript->registerScript('unique scriptname','js code',position)

Yii::app()->clientScript->registerCss('unique css','csscode','media=>print/handheld/screen')

Script Positions

CClientScript::POS_HEAD : the script is inserted in the head section right before the title element. .
CClientScript::POS_BEGIN : the script is inserted at the beginning of the body section.
CClientScript::POS_END : the script is inserted at the end of the body section.
CClientScript::POS_LOAD : the script is inserted in the window.onload() function.
CClientScript::POS_READY : the script is inserted in the jQuery's ready function.

so if you use,
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . '/script/test.js',CClientScript::POS_END);
then the script will be inserted to the body section

To register external scripts and css files

Yii::app()->clientScript->registerCssFile($yourscript_asset. '/test.css');
Yii::app()->clientScript->registerScriptFile($yourscript_asset. '/test.js')

Publishing scripts to assets directory

Asset manager in brief

CAssetManager is a Web application component that manages private files (called assets) and makes them accessible by Web clients. It achieves this goal by copying assets to a Web-accessible directory and returns the corresponding URL for accessing them.
you can compress and minify and otherwise process your assets with the asset publishing system, and it makes it easier to host your JS and CSS on a CDN since it's separate from your codebase.With assets, a component can be used easily without worrying about what files to be copied to public directories and what their URLs are
Consider a scenario, if we have two scripts which is located in scripts/testscript, the directory has two files namely test.js and test.css. We are going to publish it to asset and then we consume that files from asset directory, here is the snippet
$yourscript_asset= Yii::app()->assetManager->publish(Yii::app()->basePath . '/scripts/testscript /');

//Register JS and CSS files        
Yii::app()->clientScript->registerCssFile($yourscript_asset. '/test.css');
Yii::app()->clientScript->registerScriptFile($yourscript_asset. '/test.js');

Tips

Load files from google server

Cleans all registered scripts before any script register

Cleans all registered scripts.
Yii::app()->getClientScript()->reset();

Prevent loading jquery files

Yii::app()->clientScript->scriptMap['jquery.js'] = false;
//or if more than one script to be prevent from registering
$cs=Yii::app()->clientScript;
$cs->scriptMap=array(
'jquery.js'=>false,
'jquery.ajaxqueue.js'=>false,
'jquery.metadata.js'=>false,
);

Avoiding scripts download on AJAX renderPartial request

Suppose we created a function to display the AJAX active form and its contents are returned by a call to a controller’s action that will partially render a view.
// Just before rendering the view that
// has our activeform
Yii::app()->clientScript->corePackages = array();
Now controller doesn't return script files.
It is very important that we set corePackages to array() instead of null, as setting it to null will make CClientScript to reload the packages.php file (located in framework/web/js/) and we won’t stop the duplication of the script.