постепенный перевод сайта на новую тему yii2
есть работающий сайт, на котором надо абгрейдить дизайн и функционал. Для этого создана тема, расположение которой в структуре файлов следующее:
- Подскажите правильный алгоритм перевода сайта на эту тему.
- В идеале меня интересует такой вариант, при котором есть массив экшенов и контроллеров уже переписанных под эту тему, для которых включается новая тема. Для всего, что не входит в этот массив включаются старые виды. По мере работы над сайтом и готовности того или иного экшена или контроллера, в этот массив добавляется указание, что теперь для них подключаем новую тему и так дальше, пока все экшены не будут допилены. Можно ли организоваться так?
- Метод yii\base\ViewContextInterface::getViewPath() переключает дефолтную папку вида для всех экшенов конроллера или можно переключить для конкретных экшенов?
Частично сделал то, что мне надо, но есть небольшой косяк. Вот код
public function getViewPath()
{
$goodActions = ['search-provider1', 'index'];
if (ArrayHelper::isIn($this->action->id, $goodActions)){
// $viewPath = yii::$app->view->theme->pathMap['@app/views'].DIRECTORY_SEPARATOR.$this->id.DIRECTORY_SEPARATOR;
$viewPath = '@app/themes/neat/views/' .$this->id.DIRECTORY_SEPARATOR;
} else {
// $viewPath = 'home/oughtem/27082017.net/www/frontend/views/' .$this->id.DIRECTORY_SEPARATOR;
$viewPath = '@app/views/' .$this->id.DIRECTORY_SEPARATOR;
}
return $viewPath;
}
public function actionSearchProvider(){
$get = yii::$app->request->get();
echo '<pre>';
print_r($this->getViewPath());
//@app/themes/neat/views/site/
//@app/views/site/
return $this->render($this->action->id,[
'get' => $this->getViewPath(),
]);
// return $this->render($this->getViewPath().$this->action->id,[
// 'get' => $this->getViewPath(),
// ]);
}
Оба метода добавлены в основном контроллере. Из метода getViewPath() я могу получить нужный мне путь в зависимости от того готов у меня эшен или нет, но независимо от того какой из путей
//@app/themes/neat/views/site/
//@app/views/site/
я передаю в метод render рендерится всё равно вид из themes/neat/views/site/. Исключением является только тот случай, когда в папке themes/neat/views/site/ отсутствует файл вида. Тогда получив тот же самый ответ от getViewPath() рендерится файл из views/site/.
Из документации метода рендер
* The view to be rendered can be specified in one of the following formats: * * - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index"); * - absolute path within application (e.g. "//site/index"): the view name starts with double slashes. * The actual view file will be looked for under the [[Application::viewPath|view path]] of the application. * - absolute path within module (e.g. "/site/index"): the view name starts with a single slash. * The actual view file will be looked for under the [[Module::viewPath|view path]] of [[module]]. * - relative path (e.g. "index"): the actual view file will be looked for under [[viewPath]].
становиться ясно, что если передать path alias, то замены не должно быть, но она всё равно происходит.
Собственно вопрос несколько видоизменился: как заставить render рендерить нужный мне вид, а не переопределять его?
Ответы (2 шт):
Я бы в таком случае сделал таким образом. Учитывая, что этот костыль временный.
В параметрах project/frontend/config/params.php создаем массив, в котором укажем список контроллеров и экшенов, которые переведены на новую тему.
'upgradeView' => [
'controllerId' => ['actionId'],
]
Далее создаем трейт, в котором получим массив контроллеров из параметров и проверим наличие текущего экшена. Если если экшн для текущего контроллера переведен на новую тему, то переключим компонент view на новую тему. Выглядит приблизительно так.
Yii::$app->getView()->theme = '@app/themes/neat';
Соответственно трейт подключаем в нужные контроллеры. Переключалку темы делаем в beforeAction().
За основу логики взял ответ товарища fedornabilkin, но техническое исполнение оставил за собой, т.к. решение
Соответственно трейт подключаем в нужные контроллеры
не вызывало оптимизма. Контроллеров много и искать нужные и не нужные не особо хотелось. Сделал helper
public function hasView($controller_id, $action_id){
$good_view = [
'site' => ['index', 'static-page'],
'provider' => ['settings'],
'categories' => ['search-view'],
];
if (in_array($action_id, $good_view[$controller_id])) {
return false;
} else {
return true;
}
}
а в main.php добавил
'view' => [
'theme' => [
'class'=> yii\base\Theme::className(),
'basePath'=> '@app/themes/neat/web', // путь в дир-ию темы, базовая директория, в которой размещены темизированные ресурсы (CSS, JS, изображения, и так далее).
'baseUrl' => '@web/themes/neat/web', // базовый URL для доступа к темизированным ресурсам.
'pathMap' => [
'@app/views' => '@app/themes/neat/views',
'@app/web/img' => '@app/web/neat/img',
],
],
],
+ там же ниже
'on beforeAction' => function ($event) {
if ((\frontend\helpers\NewViewHelper::hasView(Yii::$app->controller->id, Yii::$app->controller->action->id))){
Yii::$app->view->theme = null;
}
Т.е. по дефолту переопределил всё, если нужный экшен не указан в массиве готовых экшенов сбиваю ему свойство theme в null.
