Reputation: 6084
Suppose I have a fairly standard route definition, for, say, user stuff:
'router' => array(
'routes' => array(
'user' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/user[/:action]',
'constraints' => array('action' => '[a-zA-Z0-9_-]*'),
'defaults' => array(
'controller' => 'usercontroller',
'action' => 'index',
),
),
),
),
),
Now, suppose I want to use different controllers for different groups of the 'user' actions. Say for example that one or two actions ('special' and 'super', say) should go to 'specialcontroller'. How do I configure that? I've tried using 'child_routes' to no avail, and I've tried having multiple 'user' entries in the 'routes' array, but no joy.
Upvotes: 1
Views: 714
Reputation: 6084
For those, like me, who are still learning ZF2 and would prefer a simpler version of the great answer by NonoHERON, here's the code:
'user' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/user',
'defaults' => array(
'controller' => 'usercontroller',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:action]',
'constraints' => array('action' => '[a-zA-Z0-9_-]*'),
'defaults' => array(
'controller' => 'usercontroller',
'action' => 'index',
),
),
),
'special' => array(
'type' => 'Literal',
'options' => array(
'route' => '/details',
'defaults' => array(
'controller' => 'specialcontroller',
'action' => 'special',
),
),
),
),
),
To get the '$this->url' to work in your view code, you now need to set it up slightly differently. For the actions in the default grouping, it becomes:
$this->url('user/default', array('action'=>'whatever'))
Whilst for the special, strictly, it should be:
$this->url('user/special')
However, if all you are doing is varying which controller the action goes to, then
$this->url('user/default', array('action'=>'special'))
should also work produce the correct link.
There is also a very helpful zf2 cheat sheet at: http://zf2cheatsheet.com/
Upvotes: 1
Reputation: 114
You can create a route type literal, with a child route type segment :
'router' => array(
'routes' => array(
'user' => array(
'type' => 'Literal',
'options' => array(
'route' => '/user',
'defaults' => array(
'__NAMESPACE__' => 'MyModule\Controller',
'controller' => 'User',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
),
),
),
),
),
),
),
or if you prefer, directly declare the controller name as a route parameter in a route type segment :
'router' => array(
'routes' => array(
'user' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action[/:id]]]',
'defaults' => array(
'__NAMESPACE__' => 'MyModule\Controller',
'controller' => 'User',
'action' => 'index',
),
),
),
),
),
I prefer the first way to avoid route's conflicts between modules controllers
what you can also do if you have multiples controllers for a specific section of your app (here : user), and multiples sections of your app controlled in the same module => organise your controllers in different namespaces like :
namespace MyModule\Controller\Users;
Upvotes: 3