Question

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.

Was it helpful?

Solution

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;

OTHER TIPS

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/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top