Страница модуля на витрине
Хук добавляет блок на существующую страницу. Когда модулю нужна собственная страница со своим адресом — например, все отзывы о товаре, — пишут контроллер витрины. Это класс, который получает запрос, готовит данные и выбирает шаблон.
Где лежит контроллер
Контроллеры витрины хранят в папке controllers/front, шаблоны страниц — в views/templates/front. Файлы создают вручную:
modules/acmehello/
├── acmehello.php
├── classes/
├── controllers/
│ └── front/
│ └── reviews.php
├── upgrade/
└── views/
└── templates/
├── front/
│ └── reviews.tpl
└── hook/Контроллер
<?php
// modules/acmehello/controllers/front/reviews.php
class AcmehelloReviewsModuleFrontController extends ModuleFrontController
{
public function initContent(): void
{
parent::initContent();
$this->setTemplate('module:acmehello/views/templates/front/reviews.tpl');
}
}Имя класса задано строго: имя модуля с заглавной буквы, имя файла с заглавной буквы и окончание ModuleFrontController. Метод initContent() вызывается при открытии страницы, setTemplate() выбирает шаблон.
Шаблон страницы
{* modules/acmehello/views/templates/front/reviews.tpl *}
{extends file='page.tpl'}
{block name='page_title'}
{l s='Отзывы' d='Modules.Acmehello.Shop'}
{/block}
{block name='page_content'}
<p>{l s='Здесь будет список отзывов.' d='Modules.Acmehello.Shop'}</p>
{/block}Шаблон наследует page.tpl темы и заполняет два его блока: заголовок и содержимое. Шапка, подвал и колонки подставляются сами.
Адрес страницы
Откройте http://shop.test/index.php?fc=module&module=acmehello&controller=reviews. Появится страница магазина с заголовком «Отзывы». Если в магазине включены дружественные адреса, та же страница доступна как http://shop.test/module/acmehello/reviews.
Сбрасывать модуль не нужно: контроллер находится по имени файла.
Данные в шаблоне
Контроллер читает номер товара из запроса и передаёт отзывы в шаблон. Объект модуля доступен в $this->module:
// modules/acmehello/controllers/front/reviews.php
public function initContent(): void
{
parent::initContent();
$productId = (int) Tools::getValue('id_product');
$product = new Product($productId, false, $this->context->language->id);
if (!Validate::isLoadedObject($product)) {
Tools::redirect($this->context->link->getPageLink('pagenotfound'));
}
$this->context->smarty->assign([
'productName' => $product->name,
'productUrl' => $this->context->link->getProductLink($product),
'reviews' => $this->module->getReviews($productId),
]);
$this->setTemplate('module:acmehello/views/templates/front/reviews.tpl');
}{block name='page_content'}
<p><a href="{$productUrl}">{$productName}</a></p>
{foreach from=$reviews item=review}
<article class="acme-review">
<strong>{$review.author}</strong> — {$review.rating}/5
<p>{$review.content}</p>
</article>
{foreachelse}
<p>{l s='Отзывов пока нет.' d='Modules.Acmehello.Shop'}</p>
{/foreach}
{/block}Адрес /module/acmehello/reviews?id_product=1 покажет название товара со ссылкой и все его отзывы. Для несуществующего товара откроется страница «Не найдено».
Ссылка на страницу
Адрес страницы модуля не пишут руками — его строит getModuleLink(). Добавьте ссылку в блок отзывов на карточке товара:
// modules/acmehello/acmehello.php, метод hookDisplayFooterProduct
$this->context->smarty->assign([
'reviews' => $this->getReviews($productId),
'reviewsUrl' => $this->context->link->getModuleLink('acmehello', 'reviews', ['id_product' => $productId]),
]);{* modules/acmehello/views/templates/hook/product-reviews.tpl *}
<a href="{$reviewsUrl}">{l s='Все отзывы' d='Modules.Acmehello.Shop'}</a>Аргументы getModuleLink(): имя модуля, имя контроллера и параметры запроса. Метод сам учитывает язык и дружественные адреса.
Только для вошедших
// modules/acmehello/controllers/front/reviews.php
public $auth = true;
public $authRedirection = 'my-account';С этими свойствами гостя перенаправит на страницу входа. Для страницы отзывов они не нужны, но пригодятся для страниц личного кабинета.
Частая ошибка
Класс назвали AcmeHelloReviewsController или файл — Reviews.php. Страница отдаёт 404, и в журнале нет ошибок. Движок ищет файл controllers/front/reviews.php и класс AcmehelloReviewsModuleFrontController — имена собираются из имени модуля и значения параметра controller, и отступить от этого правила нельзя.