[share] How to embed the css and images in a module

Maybe there is not a good introduction about how to embed css and images in a module in the forum (or cookbook) of Yii framework, but thanks to Qiang, who builds the great framework, that I found the way in the kernal code in framework/gii (In fact that gii is a module!)

Here is the structure of my module "admin"




| | |~modules/

| | | `~admin/

| | |   |~assets/

| | |   | |+css/

| | |   | |+images/

| | |   |+components/

| | |   |+controllers/

| | |   |+messages/

| | |   |+models/

| | |   |+views/

| | |   `-AdminModule.php*



  1. Modify the AdminModule.php, add the code as below:



private $_assetsUrl;


/**

* @return string the base URL that contains all published asset files of this module.

*/

public function getAssetsUrl()

{

if($this->_assetsUrl===null)

$this->_assetsUrl=Yii::app()->getAssetManager()->publish(Yii::getPathOfAlias('admin.assets'));

return $this->_assetsUrl;

}


/**

* @param string the base URL that contains all published asset files of this module.

*/

public function setAssetsUrl($value)

{

$this->_assetsUrl=$value;

}


public function registerCss($file, $media='all')

{

$href = $this->getAssetsUrl().'/css/'.$file;

return '<link rel="stylesheet" type="text/css" href="'.$href.'" media="'.$media.'" />';

}


public function registerImage($file)

{

return $this->getAssetsUrl().'/images/'.$file;

}



  1. Example of calling the css and images in modules/admin/layouts/main.php



//calling the css

<?php echo Yii::app()->controller->module->registerCss('main.css');?>


//calling the images

<?php echo CHtml::image(Yii::app()->controller->module->registerImage('logo.png'), "logo");?>



Have fun with Yii!

Thanks a lot!

and if 10 modules share same theme ?

extend it all from a commom module class

Sorry to bump an old post, but it’s first on the first page google search results. I have this situation:




module/

  assets/

    css/

      foo.css

    img/

      foo.png



In foo.css I want to do this:




.foo {

  background-image: url(<???path???>/img/foo.png);

  text-decoration: blink;

}



I went through a number of perambulations, and this is what I’ve wound up with. It’s similar to OP and the wiki page which points to gii as a solution. I override CWebModule with this:




<?php


class WebModule extends CWebModule {

    public $publishDirectory = false;

    public $hashByName = false;

    public $level = -1;


    private $m_assetsUrl;

    public function getAssetsUrl($hashByName = null,$level = null) {

        if(!isset($this->m_assetsUrl)) {

            if(!isset($hashByName)) {

                $hashByName = $this->hashByName;

            }

            if(!isset($level)) {

                $level = $this->level;

            }

            $this->m_assetsUrl = Yii::app()->getAssetManager()->publish(

                Yii::getPathOfAlias("{$this->id}.assets"),$hashByName

               ,level,FORCECOPY

            );

        }

        return $this->m_assetsUrl;

    } // function getAssetsUrl($hashByName,$level)


    public function publishScriptFile($relativeUrl,$hashByName = null) {

        if(!isset($hashByName)) {

            $hashByName = $this->hashByName;

        }

        if($this->publishDirectory) {

            $url = $this->getAssetsUrl($hashByName).$relativeUrl;

        }

        else {

            $url = Yii::app()->getAssetManager()->publish(

                Yii::getPathOfAlias("{$this->id}.assets").$relativeUrl

               ,$hashByName

            );

        }

        Yii::app()->clientScript->registerScriptFile($url);

        return $url;

    } // function publishScriptFile($relativeUrl,$hashByName)


    public function publishCssFile($relativeUrl,$hashByName = false) {

        if(!isset($hashByName)) {

            $hashByName = $this->hashByName;

        }

        if($this->publishDirectory) {

            $url = $this->getAssetsUrl($hashByName).$relativeUrl;

        }

        else {

            $url = Yii::app()->getAssetManager()->publish(

                Yii::getPathOfAlias("{$this->id}.assets").$relativeUrl

               ,$hashByName

            );

        }

        Yii::app()->clientScript->registerCssFile($url);

        return $url;

    } // function publishCssFile($relativeUrl,$hashByName)


    public function publishAssetFile($relativeUrl,$hashByName = false) {

        if(!isset($hashByName)) {

            $hashByName = $this->hashByName;

        }

        if($this->publishDirectory) {

            $url = $this->getAssetsUrl($hashByName).$relativeUrl;

        }

        else {

            $url = Yii::app()->getAssetManager()->publish(

                Yii::getPathOfAlias("{$this->id}.assets").$relativeUrl

               ,$hashByName

            );

        }

        return $url;

    } // function publishAssetFile($relativeUrl,$hashByName)

}; // class Module extends CWebModule



So in my config/main.php, I do this:




...

'modules' => array(

  'module' => array(

    'publishDirectory' => true

  )

)

...



Now foo.css does this:




.foo {

  background-image: url(../img/foo.png);

  text-decoration: blink;

}



And in my view files I do this:




$this->module->publishCssFile('/css/foo.css');



Like I say I went through a number of iterations where I was publishing the css and asset (image) files separately, but in the end this is what I came up with. I will probably either remove the $hashByName parameter or add another $level parameter. Using the public getAssetsUrl means that in my view I could do something like this:




Yii::app()->clientScript->registerCssFile($this->module->assetsUrl."/css/foo.css");



Which I want to avoid in favour of doing all the registration in my derived WebModule class. E.g., in prod I will ultimately want to bundle all of my css and javascript into single minified and obfuscated files. Having all the registration happen in one place makes that easier. Also, I don’t foresee a situation where I would really prefer to publish all the files individually in favour of publishing the directory, so I may take the $publishDirectory option out and make that the only mechanism.

For reference, FORCECOPY is a constant I define in a local config file I include (via php include) in my config/main.php. In dev, I set this to true.

All told, I’m not thrilled with the asset manager. I wind up with a proliferation of directories in assets which are a headache to deal with in relation to git, to say nothing of just browsing. What I really want is a dev setting I can tell it to copy my module’s asset directory smartly, i.e., by only copying any individual file if it’s newer. I’m not currently using Yii with a CDN. I presume someone’s made an asset manager that works with cloudfront or whatever. I suppose I’ll cross that bridge when I come to it.

I am entirely sure what the problem is?

Don’t use absolute paths in your css, and don’t publish to ‘assets’ when you’re not a widget (or the like), use a ‘fixed path’ directory, like when using a theme.

For your module, you merely publish the assets in the module’s init function.

Why are you using publish in your view files? :)

Here is an example:





	/**

     * Initializes the module.

     */

	public function init()

	{

		$this->setImport(array(

			'image.models.*',

			'image.components.*',

			'image.vendors.phpthumb.*',

		));


           $this->registerScripts();

	}


	/**

     * Registers the necessary CSS files.

     */

	private function registerScripts()

	{

		$assetsURL=$this->getAssetsURL();

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

	}


	/**

	* Publishes the module assets path.

	* @return string the base URL that contains all published asset files.

	*/

	private function getAssetsURL()

	{

		$assetsPath=Yii::getPathOfAlias('image.assets');


		// Republish the assets if debug mode is enabled.

		if($this->debug===true)

			return Yii::app()->assetManager->publish($assetsPath,false,-1,true);

		else

			return Yii::app()->assetManager->publish($assetsPath);

	}



hey frnds i am using carousel bootstrap for my web application … and in that i am using the module yiishop… and i am not able to set a goodlooking theme for that module… ;(

even i have set the layout as carousel for the module in init function… the view is changing but i cant access the portlets of the pages… wil u pls suggest me how to give a goodlookin theme for the yiishop module…