instead of having every view inside the global theme directory. This seems to be more organised and more according to the concept of a module as a reusable and somehow atomic entity.
If this is not possible in Yii 1.1.8, where in the code should I start looking into in order to add this feature? (and then submit a patch).
Obrigado, Gustavo. Well, this is a quick and maybe dirty hack, but it’s working fine so far
<?php
/**
* ATheme implements theme encapsulation inside modules, so you can have your
* themed views and layouts inside the module instead of inside a global directory. The
* directory must be called themes and inside there should be a directory named
* after the theme and then the views directory, with a subdirectory per
* controller and a optional layouts directory in case you have a particular
* layout for that module:
*
* protected/modules/mymodule/themes/mytheme/views/mycontroller/myview.php
* protected/modules/mymodule/themes/mytheme/views/layouts
*
* To render a view in an action you must use / like this:
*
* $this->controller->render('/myview');
*
* You must declare the theme class like:
*
* 'themeManager' => array(
* 'themeClass' => 'ATheme',
* ),
*
* in your application's components, in main.php
*
* @author MetaYii
*/
class ATheme extends CTheme
{
/**
* Finds the view file for the specified controller's view.
* @param CController $controller the controller
* @param string $viewName the view name
* @return string the view file path. False if the file does not exist.
*/
public function getViewFile($controller, $viewName)
{
$moduleViewPath = $this->getViewPath();
if (($module = $controller->getModule()) !== null) {
$moduleViewPath = $module->getBasePath() . '/themes/' . $this->getName() . '/views/' . $controller->getId();
}
return $controller->resolveViewFile($viewName, $this->getViewPath().'/'.$controller->getUniqueId(), $this->getViewPath(), $moduleViewPath);
}
/**
* Finds the layout file for the specified controller's layout.
* @param CController $controller the controller
* @param string $layoutName the layout name
* @return string the layout file path. False if the file does not exist.
*/
public function getLayoutFile($controller,$layoutName)
{
$moduleViewPath = $basePath=$this->getViewPath();
$module = $controller->getModule();
if (empty($layoutName)) {
while ($module !== null) {
if($module->layout === false)
return false;
if(!empty($module->layout))
break;
$module = $module->getParentModule();
}
if($module === null) {
$layoutName = Yii::app()->layout;
}
else {
$layoutName = $module->layout;
$moduleViewPath = $module->getBasePath() . '/themes/' . $this->getName() . '/views';
}
}
else if($module !== null) {
$moduleViewPath = $module->getBasePath() . '/themes/' . $this->getName() . '/views';
}
return $controller->resolveViewFile($layoutName, $moduleViewPath.'/layouts', $basePath, $moduleViewPath);
}
}
Since I’m not using skins, I didn’t try to get them to work under this scheme, but I think it could be done in the same way.