Шаблоны
Шаблон — файл с HTML и вставками PHP, который превращает данные в страницу. Шаблоны имеют расширение .phtml и лежат в папке view модуля. Действие контроллера передаёт в шаблон данные через объект ViewModel.
Где искать шаблоны
Сначала сообщите Laminas, что в модуле есть папка с шаблонами. Добавьте раздел в module/Blog/config/module.config.php:
// module/Blog/config/module.config.php
'view_manager' => [
'template_path_stack' => [
__DIR__ . '/../view',
],
],template_path_stack — список папок, в которых фреймворк ищет шаблоны. Здесь это module/Blog/view.
Имя файла
Путь к шаблону складывается из трёх имён в нижнем регистре: модуль, контроллер без слова Controller, действие.
| Действие | Файл шаблона |
|---|---|
PostController::indexAction() | module/Blog/view/blog/post/index.phtml |
PostController::viewAction() | module/Blog/view/blog/post/view.phtml |
PostController::addAction() | module/Blog/view/blog/post/add.phtml |
Первый шаблон
Измените действие так, чтобы оно возвращало ViewModel:
// module/Blog/src/Controller/PostController.php
use Laminas\View\Model\ViewModel;
public function indexAction()
{
return new ViewModel([
'heading' => 'Статьи',
]);
}Создайте папки module/Blog/view/blog/post и файл index.phtml:
<!-- module/Blog/view/blog/post/index.phtml -->
<h1><?= $this->escapeHtml($this->heading) ?></h1>Ключ массива heading стал в шаблоне свойством $this->heading. Откройте /blog: заголовок «Статьи» появится внутри общей рамки сайта с шапкой.
Список в шаблоне
Передайте в шаблон массив статей:
return new ViewModel([
'heading' => 'Статьи',
'posts' => [
['id' => 1, 'title' => 'Первая статья'],
['id' => 2, 'title' => 'Вторая статья'],
],
]);В шаблонах используют запись циклов и условий с двоеточием — она лучше читается среди HTML:
<!-- module/Blog/view/blog/post/index.phtml -->
<h1><?= $this->escapeHtml($this->heading) ?></h1>
<?php if (count($this->posts) === 0): ?>
<p>Статей пока нет.</p>
<?php endif; ?>
<ul>
<?php foreach ($this->posts as $post): ?>
<li><?= $this->escapeHtml($post['title']) ?></li>
<?php endforeach; ?>
</ul>На странице появится список из двух заголовков.
Экранирование
Экранирование — замена символов вроде < на безопасные коды, чтобы текст из базы или формы не превратился в HTML-теги.
| Помощник | Где применять |
|---|---|
escapeHtml($text) | Текст между тегами |
escapeHtmlAttr($value) | Значение атрибута: title, alt, value |
escapeJs($value) | Значение внутри JavaScript |
escapeUrl($value) | Часть адреса в ссылке |
Другой шаблон
Если действию нужен шаблон с другим именем, его задают явно: $view = new ViewModel(); $view->setTemplate('blog/post/list');. Имя пишут без расширения и без папки view.
Частая ошибка
Запись <?= $this->heading ?> без escapeHtml() выводит значение как есть: тег <script> из заголовка статьи выполнится в браузере посетителя. Laminas не экранирует вывод сам — оборачивайте в escapeHtml() каждое значение, которое пришло от пользователя или из базы.