Контроллеры
Контроллер — класс, методы которого формируют ответ на запрос. Маршрут из прошлого урока называет класс и метод, а контроллер решает, что показать на странице.
Где лежит контроллер
Классы модуля хранятся в папке src. Контроллеры принято класть в src/Controller. Создайте папки и файл вручную:
mkdir -p web/modules/custom/blog/src/ControllerПервый контроллер
// web/modules/custom/blog/src/Controller/BlogController.php
namespace Drupal\blog\Controller;
use Drupal\Core\Controller\ControllerBase;
class BlogController extends ControllerBase
{
public function list(): array
{
return [
'#markup' => 'Здесь будет список статей.',
];
}
}В настоящем файле первой строкой идёт <?php. Выполните drush cr и откройте /blog: появится страница сайта с заголовком «Блог» и текстом из контроллера. Шапку, меню и подвал Drupal добавил сам.
Правила именования
Drupal находит класс по пространству имён, поэтому путь к файлу и имя класса должны совпадать.
| Файл | Класс |
|---|---|
blog/src/Controller/BlogController.php | Drupal\blog\Controller\BlogController |
blog/src/Form/SubscribeForm.php | Drupal\blog\Form\SubscribeForm |
Начало Drupal\blog соответствует папке blog/src, дальше пространство имён повторяет вложенные папки.
Что возвращает метод
Метод возвращает не строку с HTML, а массив вывода — описание того, что показать. Ключ #markup означает «вывести эту разметку». Из массива Drupal сам строит страницу с оформлением темы. Массивы вывода подробно разобраны в следующей главе.
Второй метод
Для маршрута blog.about из прошлого урока добавьте в тот же класс ещё один метод:
// web/modules/custom/blog/src/Controller/BlogController.php
public function about(): array
{
return [
'#markup' => $this->t('Блог о разработке на Drupal.'),
];
}Страница /blog/about покажет этот текст. Метод $this->t() из ControllerBase делает строку переводимой — о переводе есть отдельный урок.
Другие виды ответа
Если нужна не страница сайта, а «голый» ответ, метод возвращает объект ответа:
// web/modules/custom/blog/src/Controller/BlogController.php
use Symfony\Component\HttpFoundation\JsonResponse;
public function status(): JsonResponse
{
return new JsonResponse(['status' => 'ok', 'articles' => 3]);
}Браузер получит JSON без шапки и меню. Для перенаправления на другой маршрут в ControllerBase есть метод $this->redirect('blog.list').
Что даёт ControllerBase
| Метод | Что возвращает |
|---|---|
$this->t('Текст') | Переводимую строку |
$this->currentUser() | Текущего пользователя |
$this->entityTypeManager() | Доступ к материалам и другим сущностям |
$this->config('blog.settings') | Настройки модуля |
$this->messenger() | Сообщения посетителю |
$this->redirect('blog.list') | Перенаправление на маршрут |
Частая ошибка
Сообщение о том, что класс контроллера не существует, почти всегда означает несовпадение имён. Проверьте три вещи: файл лежит именно в src/Controller, имя файла равно имени класса с учётом регистра, а namespace — Drupal\blog\Controller. В blog.routing.yml путь к классу начинается с обратной косой черты, а метод отделён двумя двоеточиями.