Automagical inclusion of CSS file

If you want to include a CSS file named with controller’s name you can insert this code in your template file:




<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/<?php echo $this->id;?>.css" />

so, if you’re in ‘site’ controller it will display:


<link rel="stylesheet" type="text/css" href="/path/to/application/css/site.css" />

In this way, you can create customized CSS file, one for each controller.

You can also include one CSS file for each controller’s action, using this code:




<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/<?php echo $this->action->id;?>.css" />

I hope it will be useful for someone :)

Much cleaner and less error prone to do this setup in your controller and use the CClientScript class to insert the references.

Like so:




public function actionIndex()

{

  $uri = 'path to your action-specific css';

  Yii::app()->clientScript->registerCssFile($uri, 'screen, projection');

}



and like this if you want controller-specific files:




public function init()

{

  $uri = 'path to your controller-specific css';

  Yii::app()->clientScript->registerCssFile($uri, 'screen, projection');

  return parent::init();

}



If you want this functionality on all controllers, create a subclass of CController, put these methods in there, and change your controllers to use the new subclass.

This works really well, it wasn’t obvious that the [b]$this->render(‘index’);

[/b] added the link tag in the document head.

Is there a way that I can define site-wide user defined scripts in this manner, as it stands it has to be included in each controller.


	public function actionIndex()

	{

		// renders the view file 'protected/views/site/index.php'

		// using the default layout 'protected/views/layouts/main.php'

		

		// this registers a bunch of css files, the render command adds them to the web doc

               $CssFiles = array('reset','text','960','site');

               foreach($CssFiles as $Css){

                   Yii::app()->clientScript->registerCssFile('/css/'.$Css.'.css', '');

               }


 		$this->render('index');

	}



I’m very new to yii

I wonder if you could explain this a little better?

Thanks,

doodle

Answered my own question

Posting this for the benefit of others:


<?php


class MyController extends CController

{


public function init(){

		// this registers a bunch of css files, the render command adds them to the web doc

        $CssFiles = array('reset','text','960','site');

        foreach($CssFiles as $Css){

               Yii::app()->clientScript->registerCssFile('/css/'.$Css.'.css', '');

        }

    }

}

Placed this file in /protected/components/

Changed CController in yiic generated controllers to MyController

Automagical! ;)

doodle

Don’t forget to call the parent’s init() method…

Well I’m not calling the init() method, is it being done for me somewhere? All controllers that I am using are created by the yiic tool.

More auto magic? because it works???

doodle

CController::init() is an empty method, there’s no explicit need to call it, although it is good form to always at least check what the ancestors are doing with a method, and better form to call the parent regardless (in case Yii implements some functionality in the parent init method).

Ok Yii is Very powerful! and flexible.

This is how I have set-up my parent controller to handle css and meta tags.


class BackendController extends CController

{

public $cssFiles = array('reset','text2','960','site2');


public function init(){

		// get the default css and meta tags

		$metaTags = array(  'description'=>'this is the page description',

                            'keywords'=>'keyword one, keyword two,keyword three',

                            'language'=>'en',

                            'generator'=>'Yii!'        

        );

        

        $this->initCss();

        $this->initMetaTags($metaTags);

        }

        

public function initCss($cssFiles = null){

		// this registers a bunch of css files, the render command adds them to the web doc

		if(!$cssFiles){

		$cssFiles = $this->cssFiles; // if no css files specified then use the default css files

        }

        foreach($cssFiles as $css){

               Yii::app()->clientScript->registerCssFile('/css/'.$css.'.css', '');

        } 

}

public function initMetaTags($metaTags = null){

		// meta tags

		if($metaTags){

        foreach(array_keys($metaTags) as $metaTag)

        {

        Yii::app()->clientScript->registerMetaTag($metaTags[$metaTag],$metaTag); 

        }

        } else {

        return;

        }

        

    }

...snip   



So each child controller now has default css and default meta tags, but usually you will want specific meta tags (especially description and in my case geo location tags) I can now do the following for controller specific (actual controller/action) specific meta tags.




class SiteKeysController extends BackendController

{

..snip..

	/**

	 * Lists all models.

	 */

	public function actionList()

	{

		$criteria=new CDbCriteria;


		$pages=new CPagination(SiteKeys::model()->count($criteria));

		$pages->pageSize=self::PAGE_SIZE;

		$pages->applyLimit($criteria);


		$models=SiteKeys::model()->findAll($criteria);

		

		// meta tags and css

		Yii::app()->clientScript->reset();  // this resets ALL registrations

		$this->initCss();

        $metaTags = array(  'description'=>'This is customized for the site keys list',

                            'keywords'=>'Yippee Kai eh!',

                            'language'=>'en',

                            'generator'=>'Yii!'        

        );

        $this->initMetaTags($metaTags);

        

		$this->render('list',array(

			'models'=>$models,

			'pages'=>$pages,

		));

	}







This works exactly the way I would like it, of course I plan to pull the values from a database for the individual pages (still on a vertical learning curve with yii).

Question:Yii::app()->clientScript->reset(); is this the only way to remove meta tags / css / javascript ?

Can items be removed individually?

Also the css and javascript files are rendered nicely (visually)


<meta content="This is customized for the site keys list" name="description" /><meta content="Yippee Ki eh!" name="keywords" /><meta content="en" name="language" /><meta content="Yii!" name="generator" /><link rel="stylesheet" type="text/css" href="/css/reset.css" />

<link rel="stylesheet" type="text/css" href="/css/text2.css" />

<link rel="stylesheet" type="text/css" href="/css/960.css" />

<link rel="stylesheet" type="text/css" href="/css/site2.css" />

<link rel="stylesheet" type="text/css" href="/assets/f913186d/treeview/jquery.treeview.css" />

<script type="text/javascript" src="/assets/f913186d/jquery.js"></script>

<script type="text/javascript" src="/assets/f913186d/jquery.cookie.js"></script>

<script type="text/javascript" src="/assets/f913186d/jquery.treeview.js"></script>

<script type="text/javascript" src="/assets/f913186d/jquery.treeview.async.js"></script>




it would be more desirable to have a cleaner output (not a big problem of course)




<meta content="This is customized for the site keys list" name="description" />

<meta content="Yippee Ki eh!" name="keywords" />

<meta content="en" name="language" />

<meta content="Yii!" name="generator" />



also content before name is unusual in meta tag definitions, I guess I would have to either (I won’t ever do this) hack the core or extend it. Is that true?

Thanks,

doodle

I think that putting the style and meta definitions in your controller may cause problems later, personally. If you put the registerCssFile, etc calls into the view file rather, then you have more flexibility in using different stylesheets and scripts for different views.

If you want the scripts and stylesheets to be used across all controllers, put the register functions calls in your views/layouts/main.php instead.

The order of attributes in HTML is not significant. Your META tags will be still be read regardless of the attribute order, as long as they are valid HTML.