Question

I would like to create a generic module/controller/action route in Zend Framework 2 to be used with ZF2 MVC architecture.

In ZF1 the default route was defined like /[:module][/:controller][/:action] where module would default to default, controller would default to index and action to index.

Now, ZF2 changed the way modules are intended, from simple groups of controllers and views, to real standalone applications, with explicit mapping of controller name to controller class.

Since all controller names must be unique across all modules, I was thinking to name them like modulename-controllername but I would like the URL to look like /modulename/controllername without the need to create specific routes for each module, using something like the old default route for ZF1 described above.

Was it helpful?

Solution

Yes it is very possible, but you will have to do a little work. Use the following config:

        'default' => array(
            'type'    => 'My\Route\Matcher',
            'options' => array(
                'route'    => '/[:module][/:controller[/:action]]',
                'constraints' => array(
                    'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                ),
                'defaults' => array(
                    'module'     => 'default',
                    'controller' => 'index',
                    'action'     => 'index',
                ),
            ),
        ),

Then you have to write your own My\Route\Matcher to create a Routemap object that the MVC can use. It's not hard, look at the other route matchers already in the framework and you'll get the idea.

OTHER TIPS

If you use the Zend Skeleton Application you have already configured this default controller.

See here https://github.com/zendframework/ZendSkeletonApplication/blob/master/module/Application/config/module.config.php

To have a general/standard routing system for a zf2 module, this is my solution for just one controller "module\controller\index" ( default controller ) :

'router' => array(
    'routes' => array(              
        'default' => array(
            'type'    => 'Literal',
            'options' => array(
                'route'    => '/', // <======== this is take the first step to our module "profil"
                'defaults' => array(
                    'module'     => 'profil',
                    'controller' => 'profil\Controller\Index',
                    'action'     => 'index',
                ),
            ),
        ),              
        'profil' => array(
            'type'    => 'Segment',
            'options' => array(
                'route'    => '/[profil][/:action]', // <======== this is take the next steps of the module "profil"
                'constraints' => array(
                    'module' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                ),
                'defaults' => array( // force the default one
                    'module'     => 'profil',
                    'controller' => 'profil\Controller\Index',
                    'action'     => 'index',
                ),
            ),
        ),
    ),
),

then in our controller "profil\Controller\Index" we have three actions "index" "home" "signout" :

public function indexAction()
{
        if ($this->identity()) {
            return $this->redirect()->toRoute('profil',array('action'=>'home'));
        } else {
            // ......
                    $authResult = $authService->authenticate();
                    if ($authResult->isValid()) {
                            //......
                                                    return $this->redirect()->toRoute('profil',array('action'=>'home'));
                    } else {
                        // ......
                    }
                } else {
                    $messages = $form->getMessages();
                }
            }               
            return new ViewModel();
        }
}

public function homeAction()
{
    if (!$this->identity()) {
        return $this->redirect()->toRoute('profil',array('action'=>'signout'));
    }
}

public function signoutAction()
{
    if ($this->identity()) {
        $authService = $this->getServiceLocator()->get('Zend\Authentication\AuthenticationService');
        $authService->clearIdentity();
    }
    $this->redirect()->toRoute('profil');
}  

and thank you anyway :)

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