Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Страница модуля на витрине

Хук добавляет блок на существующую страницу. Когда модулю нужна собственная страница со своим адресом — например, все отзывы о товаре, — пишут контроллер витрины. Это класс, который получает запрос, готовит данные и выбирает шаблон.

Где лежит контроллер

Контроллеры витрины хранят в папке 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, и отступить от этого правила нельзя.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.