Пересаживаюсь с CodeIgniter на Yii, решил накропать тестовый проект.
Прочитал http://www.yiiframework.com/wiki/63/ про разделение frontend\backend. Всё круто, всё получилось.
Решил прикрутить темы, и тут выяснился досадный факт
-
WebApplicationEndBehavior при инициализации приложения подменяет пути для разделения frontend\backend
-
Когда контроллер вызывает render вьюхи, проверяется, активна ли какая-нибудь тема или нет
-
Если тема неактивна, то файл вьюхи ищется с использованием подмененных путей (в frontend или backend частях)
-
А вот если тема активна, то файлы ищутся в путях, которые определяются внутри CTheme вот так:
public function getViewPath()
{
return $this->_basePath.DIRECTORY_SEPARATOR.'views';
}
Соответственно ни о каких разделениях frontend\backend внутри темы речи уже не идёт.
Как проблему решил я:
Создал CThemeManagerEndBehavior.php
class CThemeManagerEndBehavior extends CBehavior
{
// Web application end's name.
// private $_endName;
// Getter.
// Allows to get the current -end's name
// this way: Yii::app()->endName;
private static $end;
public function attach($component){
parent::attach($component);
$component->themeClass = 'CEndedTheme';
}
public static function setApplicationEnd($end){
self::$end = $end;
}
public static function getApplicationEnd(){
return self::$end;
}
}
Сломал метод runEnd у WebApplicationEndBehavior
public function runEnd($name)
{
Yii::trace("Running {$name}end", 'system.web.WebApplicationEndBehavior');
$this->_endName = $name;
CThemeManagerEndBehavior::setApplicationEnd($name);
// Attach the changeModulePaths event handler
// and raise it.
$this->onModuleCreate = array($this, 'changeModulePaths');
$this->onModuleCreate(new CEvent($this->owner));
$this->owner->run(); // Run application.
}
Прикрутил behavior к СThemeManager в конфиге
'themeManager'=>array(
'behaviors' => array(
'runEnd' => array( 'class'=>'application.components.CThemeManagerEndBehavior' )
)
)
В CEndedTheme переопределил getViewPath
class CEndedTheme extends CTheme{
public function getViewPath()
{
return parent::getViewPath().DIRECTORY_SEPARATOR.CThemeManagerEndBehavior::getApplicationEnd();
}
}
Всё работает, но осадочек неприятный от статических переменных остался
Гуру, может есть какой-то более рациональный подход?