Массивы вывода
Контроллер Drupal возвращает не готовый HTML, а массив вывода (render array) — описание того, что нужно показать. Разметку из него строит система оформления. Благодаря этому тема сайта и другие модули могут изменить вывод, не трогая ваш код.
Простейший массив
// web/modules/custom/blog/src/Controller/BlogController.php
public function list(): array
{
return [
'#markup' => '<p>Здесь будет список статей.</p>',
];
}Страница /blog покажет абзац с текстом. Ключ с решёткой — свойство: #markup означает «вывести эту разметку».
Вложенные элементы
Ключи без решётки — вложенные элементы. Каждый из них — такой же массив вывода:
// web/modules/custom/blog/src/Controller/BlogController.php
public function list(): array
{
return [
'intro' => [
'#markup' => '<p>Свежие статьи блога.</p>',
],
'articles' => [
'#theme' => 'item_list',
'#items' => ['Первая статья', 'Вторая статья', 'Третья статья'],
],
];
}На странице появятся абзац и под ним маркированный список из трёх пунктов. Элементы выводятся в порядке записи; имена intro и articles вы выбираете сами.
Два вида элементов
Свойство #theme называет шаблон, которому передаются остальные свойства: item_list — шаблон списка из ядра. Свойство #type называет готовый элемент с собственной логикой: таблицу, ссылку, поле формы.
| Запись | Что выводит |
|---|---|
'#markup' => '…' | Разметку. Опасные теги вырезаются |
'#plain_text' => '…' | Текст с полным экранированием |
'#theme' => 'item_list' | Список: #items, #title |
'#type' => 'table' | Таблицу: #header, #rows |
'#type' => 'link' | Ссылку: #title, #url |
'#type' => 'html_tag' | Один тег: #tag, #value |
'#type' => 'details' | Раскрывающийся блок: #title |
Ссылка
// web/modules/custom/blog/src/Controller/BlogController.php
use Drupal\Core\Url;
$build['about'] = [
'#type' => 'link',
'#title' => $this->t('О блоге'),
'#url' => Url::fromRoute('blog.about'),
];Элемент выведет ссылку на маршрут blog.about. Адрес задаётся объектом Url, а не строкой.
Таблица
// web/modules/custom/blog/src/Controller/BlogController.php
$build['table'] = [
'#type' => 'table',
'#header' => [$this->t('Статья'), $this->t('Автор')],
'#rows' => [
['Первая статья', 'Anna'],
['Вторая статья', 'Ivan'],
],
'#empty' => $this->t('Статей пока нет.'),
];Каждая строка #rows — массив ячеек. Если строк нет, вместо таблицы выводится текст из #empty.
Общие свойства
| Свойство | Для чего |
|---|---|
#prefix, #suffix | Разметка до и после элемента |
#attributes | Атрибуты тега, например ['class' => ['blog-list']] |
#weight | Порядок среди соседних элементов |
#access | FALSE — не выводить элемент |
#attached | Подключение стилей и скриптов |
#cache | Правила кеширования |
Последние два свойства разобраны в отдельных уроках.
Частая ошибка
Свойство #markup пропускает безопасные теги вроде strong и a, поэтому не годится для текста от посетителя, который нужно показать как есть. Для него используйте #plain_text: там экранируется всё. И не собирайте HTML склейкой строк из данных пользователя — для разметки есть шаблоны Twig, о них следующий урок.