Вложенные маршруты
У страниц одного раздела адреса начинаются одинаково: /blog, /blog/5, /blog/add. Чтобы не повторять общую часть в каждом маршруте, маршруты вкладывают друг в друга. Вложенный (дочерний) маршрут продолжает адрес родителя и наследует его значения по умолчанию.
Родитель и дочерний маршрут
В прошлом уроке маршруты blog и post были записаны отдельно. Перепишите раздел router в module/Blog/config/module.config.php так:
// module/Blog/config/module.config.php
'router' => [
'routes' => [
'blog' => [
'type' => Literal::class,
'options' => [
'route' => '/blog',
'defaults' => [
'controller' => Controller\PostController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'view' => [
'type' => Segment::class,
'options' => [
'route' => '/:id',
'constraints' => ['id' => '[0-9]+'],
'defaults' => ['action' => 'view'],
],
],
],
],
],
],Адрес дочернего маршрута приклеивается к адресу родителя: /blog плюс /:id даёт /blog/5. Контроллер у дочернего маршрута не указан — он взят у родителя, меняется только действие.
Ключ may_terminate
'may_terminate' => true означает, что адрес родителя — /blog — тоже рабочая страница. Без этого ключа сработают только дочерние маршруты, а сам /blog вернёт ошибку 404.
Все маршруты блога
Добавьте в child_routes ещё три маршрута — они понадобятся в следующих уроках:
'add' => [
'type' => Literal::class,
'options' => [
'route' => '/add',
'defaults' => ['action' => 'add'],
],
],
'edit' => [
'type' => Segment::class,
'options' => [
'route' => '/edit/:id',
'constraints' => ['id' => '[0-9]+'],
'defaults' => ['action' => 'edit'],
],
],
'delete' => [
'type' => Segment::class,
'options' => [
'route' => '/delete/:id',
'constraints' => ['id' => '[0-9]+'],
'defaults' => ['action' => 'delete'],
],
],Получается такая таблица:
| Имя маршрута | Адрес | Действие |
|---|---|---|
blog | /blog | index |
blog/view | /blog/5 | view |
blog/add | /blog/add | add |
blog/edit | /blog/edit/5 | edit |
blog/delete | /blog/delete/5 | delete |
Имена вложенных маршрутов
Имя дочернего маршрута записывают через косую черту после имени родителя. Ссылку на статью теперь строят так:
$url = $this->url('blog/view', ['id' => 5]); // /blog/5Отдельного маршрута post из прошлого урока больше нет — его заменил blog/view.
Частая ошибка
Если обратиться к дочернему маршруту без имени родителя — $this->url('view', ['id' => 5]), — Laminas выбросит исключение о том, что маршрут с таким именем не найден. Имя всегда полное: blog/view. Вторая похожая ошибка — забытый may_terminate: дочерние страницы открываются, а /blog отвечает 404.