I don't like to use keywords like category
and article
in the URLs. That's the reason I am using the following route for my blog with embedded child routes. It makes easier using the same controller with different actions for blog index, category index and article.
<?php
namespace Application;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
return [
// ...
'router' => [
'routes' => [
'blog' => [
'type' => Literal::class,
'options' => [
'route' => '/blog/',
'defaults' => [
'controller' => Controller\BlogController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'category' => [
'type' => Segment::class,
'options' => [
'route' => ':category[/:page]/',
'constraints' => [
'category' => '[a-zA-Z][a-zA-Z0-9_-]*',
'page' => '[0-9]+',
],
'defaults' => [
'action' => 'category',
],
],
'may_terminate' => true,
'child_routes' => [
'article' => [
'type' => Segment::class,
'options' => [
'route' => ':article/',
'constraints' => [
'article' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'action' => 'article',
],
],
],
]
],
]
],
],
],
// ...
],
However, the child route with the parent child route having [:page]
parameter caused following error even it is an optional parameter where I have URL helper trying to create a url for any article
link.
To solve this problem, I used a second first level child route instead inner one for the article
. I considered the fact that I don't have an article alias consist of integer only. This way the blog/category
route is only responsible for the paging since it is tracked by the [:page]
numeric value while the blog/article
route monitors article urls called by category and article aliases.
Here is the revised routing:
<?php
namespace Application;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
return [
// ...
'router' => [
'routes' => [
'blog' => [
'type' => Literal::class,
'options' => [
'route' => '/blog/',
'defaults' => [
'controller' => Controller\BlogController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'category' => [
'type' => Segment::class,
'options' => [
'route' => ':category[/:page]/',
'constraints' => [
'category' => '[a-zA-Z][a-zA-Z0-9_-]*',
'page' => '[0-9]+',
],
'defaults' => [
'action' => 'category',
'page' => 1,
],
],
],
'article' => [
'type' => Segment::class,
'options' => [
'route' => '/:category/:article/',
'constraints' => [
'category' => '[a-zA-Z][a-zA-Z0-9_-]*',
'article' => '[a-zA-Z][a-zA-Z0-9_-]*',
],
'defaults' => [
'action' => 'article',
],
],
],
],
],
],
],
// ...
],