It works fine, in a module retrive module/module_id/views/layout/main.php and, if theme/themeId/module/module_id/views/layout/main.php is defined, it retrive the second one.
A function cannot be used in
public $layout =...
that mean that you have to implement some beforeAction or smth like that for set.
How to do with namespace (and avoid to implement beforeAction) i don’t know, maybe is not possible.
CTheme is a nice stuff, very powerfull, but is a bit difficoult to do smth that is not "rendering a view". Even "rendering a layout view" is difficoult.
If you find a better solution, tell me. If not, my suggestion works
The getLayoutFile search first under the active theme directory and if don’t find it search under the ordinary path.
The philosophy of theming is to change the view to render, so you need a view for each theme you want to implement. Usually I use a main.php view static in wich I render a small view only for css inclusion.
That avoid the problem of replicate the code that there is in main.php (eg mainmenu).
Overview on path alias and theming are in The definitive guide to Yii
I think you don’t have to put that code inside init() function of BlogModule if it extends CWebModule, as I suppose.
I’ve done in this way: I have a main controller inside ‘components’ dir, for example MyController.php. Inside init() function of that I’ve put code above. After that I declare that other controllers extends MyController.
This rule is valid also for modules’ controllers. So inside protected/modules/myModule/controller/ModuleController.php I have something like this:
class ModuleController extends MyController
{
// put your code here...
}
so it inherits layout setting from MyController (but of course you can override inside ModuleController). I think init() in CWebModule refers to something else.
Personnally, i’ve chosen to not modify gii generated class that contains $layout=’//layouts/*’ path.
Instead, i use a beforeAction method in global component Controller.php :
/**
* Manage theme layout is overriden.
* If given layout is overriden, use it instead of protected folder one. Else, use protected folder one.
* @see CController::beforeAction()
*/
public function beforeAction($action)
{
// If application is using a theme, replace default layout controller variable that start with '//layouts/' with a theme link
if(empty(Yii::app()->theme->name) == false && isset($this->layout) == true && strpos($this->layout, '//layouts/') === 0)
{
// Replace path with slash by dot.
$sThemeLayout = 'webroot.themes.'.Yii::app()->theme->name.'.views.layouts.'.str_replace('/', '.', substr($this->layout,10));
// If theme override given layout, get it from theme
if($this->getLayoutFile($sThemeLayout) !== false)
$this->layout = $sThemeLayout;
}
return true;
}