Такой забавный вопрос может посетить вас конечно не при первом знакомстве с OpenCart, но довольно скоро.
Банальная задача с точки зрения менеджера по контекстной рекламе в вашей компании или компании-заказчике вроде поместить в шапку сайта код для ремаркетинга Google может вызвать легкое недомогание у разработчика на OpenCart. Давайте разберемся в чем проблема и как с ней бороться.
Для начала в чем проблема? Код ремаркетинга как правило нужно размещать в шапку сайта, повыше и поближе к другим кодам Google. Выглядит он примерно так:
window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'AW-123456789'); gtag('event', 'page_view', { 'send_to': 'AW-123456789', 'ecomm_prodid': 'REPLACE_WITH_STRING_VALUE', 'ecomm_pagetype': 'REPLACE_WITH_STRING_VALUE', 'ecomm_totalvalue': 'REPLACE_WITH_STRING_VALUE' });
Если бы код был статический, то разработчик просто вставлил его в соответстующий блок header.tpl
, но в данном случае у нас код динамический, т.е. в код входят переменные, содержащие данные конкретного товара. Вот тут и кроется проблема. ID товара, его цена и др. поля по-умолчанию получает контроллер product.php, который подключает в себя в качестве дочерних контроллеры header.php
, footer.php
и пр.
$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');
Метод ядра $this->load->controller('path/to/controller');
не принимает в качестве аргументов других переменных кроме $route
, т.е. пути до нашего подключаемого контроллера.
На эту проблему разработчику системы Daniel Kerr внимание уже обращали, но пока это не дало результата. Автор вполне резонно замечал:
no it can’t be done because can not reference an unknow number of arguments. need to wait for php to fix loads of stuff
Шапка сайта и сама страница продукта или скажем категории имеют различные контроллеры, поэтому такой уровень абрстрации нам не подходит.
Вот тут нам весьма кстати пригодится библиотка Document
. Ее преимущество в том, что она не зависит от контроллеров как таковых и к ней можно обратиться напрямую используя $this->document->yourMethod();
. В базовом виде она выглядит так (полный код под катом):
При всей своей простоте в коде, библиотека Document
отвечает за большое число данных, которые видит пользователь и браузер. В частности она устанавливает мета-теги <title>
, <meta name="description" content=" ">
, через ее переменные ядро OpenCart и его модули записывают и выводят большинство css
и js
файлов. В целом библиотека очень важна и заслуживает отдельной статьи исключительно про себя любимую. В дополнительных статьях вы можете найти статью, как подключить js-файл в footer
вашего сайта.
Структурно она представляет собой 3 логических блока:
- блок с объявлением переменных или массивов;
- методы
setSomething();
- методы
getSomething();
Используя эту систему мы можем добавить сюда несколько своих методов для хранения/выведения например ID текущего товара
, его Цены
и любых других данных, которые нам могут понадобиться. Давайте сделаем это на примере ID товара, а опытный читатель сможет транспонировать полученный опыт для других сущностей.
private $product_id; public function setProductId($product_id) { $this->product_id = $product_id; } public function getProductId() { return $this->product_id; }
Не забудьте сохранить ваши правки :)
Теперь в product.php
, где-нибудь после:
$product_info = $this->model_catalog_product->getProduct($product_id);
$this->document->setProductId($product_info['product_id']);
header.php
пишем:if (isset($this->request->get['route']) && $this->request->get['route'] == 'product/product') { $data['product_id'] = $this->document->getProductId; } else { $data['product_id'] = 0; }
.tpl
уверен, вы прекрасно знаете :)
вот здесь добавить скобки getProductId() и будет работать
$data[‘product_id’] = $this->document->getProductId;
Спасибо за материал, помог лучше понять MVC в опенкарте. На Опенкарт 3.0.2.0 работает, жаль что при обновлении слетит, надо ocmod делать.