Другой шаблон при определенных условиях

Для определенных условий хочу сделать что-бы подключался другой шаблон. В header.php добавляю:

if(...){
    $this->config->set('config_theme', 'theme_other');
} else {
    $this->config->set('config_theme', 'theme_default');
}

но шаблон подключается стандартный. Подскажите, пожалуйста, как подключить другой шаблон?

opencart 2.3


Ответы (1 шт):

Автор решения: Kirill

За для общего понимания:

Определение темы, на уровне любого контроллера, просходит на этапе рендера представления этого самого контроллера: $this->response->setOutput($this->load->view('some/route', $data));

$this->load->view() - метод экземпляра класса Loader(). Он, в свою очередь, запускает event-триггеры, среди которых будет before-триггер для данного контроллера. В результате вызывается метод override класса ControllerEventTheme (controller/event/theme.php) И уже в нём проверяется активная тема, сетится в конфиг в registry и отдаётся на обработку Твигу, который отдаёт в $this->response->setOutput() готовый html.

header.php, в котором вы пытаетесь поменять тему, является лишь составной частью того контроллера, который будет вызван по роуту (категория, катра товара, корзина и т.п.) - $data['header'] = $this->load->controller('common/header'); Подменять тему имеет смысл именно перед рендером страницы, т.е. перед $this->response->setOutput($this->load->view('some/route', $data)); именно в контроллере активного роута (т.е. роута, который был вызван через браузер).

Есть два нюанса. Во-первых, предётся выполнять проверку по условию и сет темы в каждом контроллере, который так или иначе задействован в рендере (или по крайней мере в первом вызваном.). А это как минимум:

$data['column_left'] = $this->load->controller('common/column_left');
$data['column_right'] = $this->load->controller('common/column_right');
$data['content_top'] = $this->load->controller('common/content_top');
$data['content_bottom'] = $this->load->controller('common/content_bottom');
$data['footer'] = $this->load->controller('common/footer');
$data['header'] = $this->load->controller('common/header');

Потому что они вызываются раньше, чем основной setOutput главного контроллера. Но так же придётся следить за возвращением прежней темы, хз куда пользователь решит перейти по сайту, а это соответствующие проверки считай по всем контроллерам, такое...

Во-вторых, скорее всего всё будет заканчиваться ошибкой Error: A theme has not been assigned to this store!, потому что тема должна быть активна для данного магазина на ряду с текущей "активной" темой. И я хз, можно так или нет.

Если уже надо замарачиваться с оригинальным дизайном, наверное луше наплодить клонов шаблонов и по условию рендерить через них. Например:

рендер категории через разные шаблоны по условию
- копируете category.twig, переименовываете в category_some.twig, стилите, редизайните

controller/product/category.php
...
...
if (some_conditions) {
    $this->response->setOutput($this->load->view('product/category', $data));
} else {
   $this->response->setOutput($this->load->view('product/category_some', $data));
}

UPD: В ответе я указывал twig-файлы, которые начали использоваться в opencart с версии 2.3, в которой ещё параллельно остаётся поддержка .tpl. Но это не меняет суть, определение темы происходит одинаково как в oc2.3, так и в oc3

→ Ссылка