Encodera

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

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

Оглавление

Шаблоны Smarty

Собирать HTML строками в PHP неудобно и небезопасно. На витрине PrestaShop разметку пишут в шаблонах Smarty — файлах .tpl, где HTML перемешан с простыми командами в фигурных скобках. Модуль передаёт в шаблон переменные и получает готовую строку.

Где лежат шаблоны

Шаблоны модуля хранят в папке views/templates, шаблоны для хуков — в подпапке hook. Создайте файл вручную:

modules/acmehello/
├── acmehello.php
├── logo.png
└── views/
    └── templates/
        └── hook/
            └── home.tpl

Первый шаблон

{* modules/acmehello/views/templates/hook/home.tpl *}
<section class="acme-hello">
    <h2>{$greeting}</h2>
</section>

Строка в {* *} — комментарий Smarty, в страницу он не попадает. {$greeting} выводит переменную.

Вывод шаблона из хука

// modules/acmehello/acmehello.php
public function hookDisplayHome(array $params): string
{
    $this->context->smarty->assign([
        'greeting' => 'Добро пожаловать!',
    ]);
 
    return $this->fetch('module:acmehello/views/templates/hook/home.tpl');
}

assign() передаёт переменные в шаблон, fetch() возвращает готовый HTML. Обновите главную страницу: приветствие теперь в заголовке h2. Сбрасывать модуль не нужно — подписка на хук не менялась.

Путь начинается с module: и имени модуля. Благодаря этому тема может подменить шаблон своим — об этом в уроке о темах.

Условия и циклы

Создайте второй шаблон — для блока отзывов на карточке товара:

{* modules/acmehello/views/templates/hook/product-reviews.tpl *}
<section class="acme-reviews">
    <h3>Отзывы</h3>
 
    {if $reviews}
        <ul>
            {foreach from=$reviews item=review}
                <li>{$review.author}: {$review.rating} из 5</li>
            {/foreach}
        </ul>
    {else}
        <p>Отзывов пока нет.</p>
    {/if}
</section>
// modules/acmehello/acmehello.php
public function hookDisplayFooterProduct(array $params): string
{
    $this->context->smarty->assign([
        'reviews' => [
            ['author' => 'Анна', 'rating' => 5],
            ['author' => 'Борис', 'rating' => 4],
        ],
    ]);
 
    return $this->fetch('module:acmehello/views/templates/hook/product-reviews.tpl');
}

На странице любого товара появится список из двух отзывов. Пока они заданы массивом; в уроке о базе данных их заменит запрос.

Синтаксис

ЗаписьЧто делает
{$name}Выводит переменную
{$review.author}Элемент массива или свойство
{if $a > 1}...{elseif ...}...{else}...{/if}Условие
{foreach from=$list item=row}...{foreachelse}...{/foreach}Цикл; foreachelse — если список пуст
{$text|truncate:100}Модификатор: обрезать до 100 символов
{$price|string_format:'%.2f'}Модификатор: формат числа
{include file='module:acmehello/views/templates/hook/stars.tpl'}Вставить другой шаблон

Готовые переменные

На витрине в любом шаблоне уже есть переменные движка: $customer, $cart, $currency, $language, $shop, $urls.

{if $customer.is_logged}
    <p>Здравствуйте, {$customer.firstname}!</p>
{else}
    <a href="{$urls.pages.authentication}">Войти</a>
{/if}

Вошедший покупатель увидит своё имя, гость — ссылку на страницу входа.

Экранирование

На витрине Smarty настроен так, что каждая переменная при выводе экранируется: символы < и > превращаются в безопасные коды, и текст отзыва не может стать скриптом. Чтобы вывести переменную как HTML, добавляют nofilter:

<div class="acme-text">{$html nofilter}</div>

Так выводят только HTML, который подготовили вы сами или ядро. В шаблонах панели управления автоматического экранирования нет — там пишут {$name|escape:'html':'UTF-8'}. В чужих модулях этот модификатор встречается и на витрине: он там безвреден.

Частая ошибка

Текст отзыва выводится с видимыми тегами, и чтобы «починить» это, к переменной дописывают nofilter. Теперь отзыв со скриптом выполнится у каждого посетителя — это уязвимость XSS. nofilter допустим только для содержимого, которое не вводил пользователь или которое прошло очистку.

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

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