paolo@bimodesign.com | +34 608 61 64 10

Framework

        

Zend 2 - routing

Routing is the act of matching a request to a given controller and a route is based on a key and contains some options. All configuration (including routes) from all modules are combined into one config array and it places into the file called module.config.php In this post I'll show some routing configuration including "child routing" and the type "segment". By this first example I'm going to explain how configure the array in the module.config.php, in order to have these web link structure:

http://zendmongoske.localhost/
http://zendmongoske.localhost/user
http://zendmongoske.localhost/user/create/
http://zendmongoske.localhost/user/edit/
http://zendmongoske.localhost/login
http://zendmongoske.localhost/logout

All actions referring to the UserController. The user route will point to profileAction while the home ("/") to the home page.
To manage the create and edit route, will need to create a child structure into the module.config.php referring to the user mainly route.
It's the code

return array(
    'router' => array(
        'routes' => array(
            'user' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/user',
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'profile',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
                    'create' => array(
                        'type' => 'Literal',
                        'options' => array(
                            'route'    => '/create',
                            'defaults' => array(
                                'controller' => 'User\Controller\User',
                                'action'     => 'create',
                            ),
                        ),
                    ),
                    'edit' => array(
                        'type' => 'Literal',
                        'options' => array(
                            'route'    => '/edit',
                            'defaults' => array(
                                'controller' => 'User\Controller\User',
                                'action'     => 'edit',
                            ),
                        ),
                    ),
                ),
            ),      

        ),
    ),
...
... the other configuration
);

Note that we need to add the

'may_terminate' => true,

in order to manage the user link route.

Now we'll add the login and logout routing in this simply way.

return array(
    'router' => array(
        'routes' => array(
            
            'login' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/login',
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'login',
                    ),
                ),
            ),
            
            'logout' => array(
                'type'    => 'Literal',
                'options' => array(
                    'route'    => '/logout',
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'logout',
                    ),
                ),
            ),
            ...
	    ... the user routing configuration
	    ...
        ),
    ),
...
... the other configuration
);

Finally to manage the home page we'll add this configuration

return array(
    'router' => array(
        'routes' => array(
            'home' => array(
                'type' => 'Literal',
                'options' => array(
                    'route'    => '/', 
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'index',
                    ),
                ),
            ),
            
            ...
	    ... the user routing configuration
	    ...
        ),
    ),
...
... the other configuration
);

Just make sure you have the proper route to slash (/) and the first in the alphabetical hierarchy of the other modules.

The second example is to using the optional route constraints in child routes like:

http://zendmongoske.localhost/user/2
http://zendmongoske.localhost/user/2/create
http://zendmongoske.localhost/user/2/edit

In this case will modify the only user routing in this way:

return array(
    'router' => array(
        'routes' => array(
            'user' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/user[/:id]',
                    'constraints' => array(
                        'id' => '[0-9]*',
                    ),
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'profile',
                    ),
                ),
                'may_terminate' => true,
                'child_routes' => array(
		    ...
		    ... the other routing configuration
		    ...
        ),
    ),
...
... the other configuration
);

Note that this configuration allows only numeric ID. If we need alfanumeric will change to

'id'     => '[a-zA-Z][a-zA-Z0-9_-]*',

and so on.

Finally if we need also these configuration

http://zendmongoske.localhost/user/11
http://zendmongoske.localhost/user/create
http://zendmongoske.localhost/user/edit
http://zendmongoske.localhost/user/edit/11

without the ID, we'll change to:

return array(
    'router' => array(
        'routes' => array(
            'user' => array(
                'type'    => 'segment',
                'options' => array(
                    'route'    => '/user[/:action][/:id]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',                        
                        'id' => '[0-9]*',
                    ),
                    'defaults' => array(
                        'controller' => 'User\Controller\User',
                        'action'     => 'profile',
                    ),
                ),
                'may_terminate' => true,
		    ...
		    ... the other routing configuration
		    ...
        ),
    ),
...
... the other configuration
);

This will make it optional to have action and/or id.

Edit 03/08/2015 - Routing with language
If you want to use this configuration

site.com (english)
site.com/de/ (german)
site.com/fr/ (france)
site.com/nl/ (dutch)

where "english" is "en" and is the default language, then the routing configuration will use the child routes and default option:

'router' => array(
    'routes' => array(
        'home' => array(
            'type' => 'literal',
            'options' => array(
                'route'    => '/',
                'defaults' => array(
                    'controller' => 'Application\Controller\Index',
                    'action'     => 'index',
                ),
            ),
            'may_terminate' => true,
            'child_routes' => array(
                'language' => array(
                    'type'    => 'segment',
                    'options' => array(
                        'route' => '[/:lang]',
                        'defaults' => array(
                            'lang' => 'en', //default
                        ),
                        'constraints' => array(
                            'lang' => '(en|de|fr|nl)?',
                        ),
                    ),
                ),
            ),
        ),
    ),
),