In ZF1 you did not have to include the module in the URL; if it was not provided, it would default to... the default module. How can this be accomplished in ZF2? I have used the skeleton application to get up and running, but it seems as if I always need to include the module name, e.g. /application/controller/action
.
I figured I could work around this by creating a route with two "placeholders"; controller and action, and then set the default module to "application". I would then put this in /config/autoload/global.php
(or perhaps /config/application.config.php
) so that the route applies for all of my application. However, I am getting the error message that the URL could not be matched by routing, even if I hard code the route to something like /user/index
.
I tried the code below.
return array(
'router' => array(
'routes' => array(
'nomodule' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/:controller/:action',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
'module' => 'Application' // Not sure of the syntax here
)
)
),
)
)
);
As I wrote as a comment, I am not sure if my problem is with the defaults syntax, but I wouldn't think so as the same happens if I hard code the route and remove all defaults. I also tried to experiment with it based on examples in the skeleton application, but without luck. Am I going about it the wrong way? Is there a better approach? Or did I just make a mistake?
Thanks in advance.
Edit: For the code to make it work, see the answer. For an explanation of how it works, read this article.
I'm new to ZF in general and I just started learning it, so tried this and it worked for me. Just to be sure, u want to change your default module when you go to your domain URL and don't type in a controller name, right?
Go to your module.config.php
As I stated in comment under @Xerkus answer, it doesn't work for all URLs:
I have added also
testAction()
toIndexController
andTestController
with same actions asIndexController
, so I could test my solution on following routes as well:So after some research (here and here mainly) I prepared solution working for all of them. I will paste my whole
module.config.php
array:In comparison with Zend 2 Skeleteon Application config I've added
noModule
route, and newcontroller invokable
-test
. Of coursenoModule
route includesApplication/Controller
namespace, so basing on this fact, you can set whatever default module you need. Now it works as it should.Of course remember that your
noModule
route should be defined in first module fromapplication.config.php
to ensure that it will always take precedence. Also remember that default module solution should be done carefully, to avoid conflicts between controllers and modules names, e.g. if you name your next moduleIndex
, then clearly you will have a naming conflict withIndexController
inApplication
module.Note: Explicit routes are strongly recommended over wildcard.
You used Zend\Mvc\Router\Http\Literal route type in your attempt, as you might guess it is literal, ie exact match. To make it work you need segment route type.
Check
application
route in Zend Skeleton Application config and it's child routedefault
. It does exactly what you are trying to do.As for modules - there is no such thing as 'module' from your code perspective. Module registers resources on startup and it is no longer relevant after that point. In zf2 you specify exact controller by class or alias name under which controller registered with controllerManager