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.