When trying to assemble a route by calling
return $this->redirect()->toRoute('application');
in my controller I get the following exception:
Zend\Mvc\Router\Exception\RuntimeException
File: library\Zend\Mvc\Router\Http\Part.php:181
Message: Part route may not terminate
the route is configures as following:
'routes' => array(
'application' => array(
'type' => 'Segment',
'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(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'child_routes' => array(
'wildcard' => array(
'type' => 'Wildcard',
),
),
),
),
Is it required to have the controller/action route as a child route from the route /?
when I configure it like that it works. When I use the route [/[:controller[/[:action[/]]]]] (with optional leading slash) it works for some assemblies but not for all and they're all called in the same way described above, partially from other modules.
The error already tells you the problem: You're missing a may_terminate option in your current route. Therefore, you can't short-circuit it by return the redirect() plugin return value.
Just add a
'may_terminate' => true
to your route's config (probably to all route configurations).
Related
This is my last chance. I tried loooking for answers, but seriously, I can't see what I'm doing wrong...
I'm trying to set up a multi-domain on a website.
Everything is working fine when using literal routes.
When adding the other domain with Hostname route, still OK.
But when adding child_routes to that Hostname route, the parent route shoots a 404.
Here's my module.config :
'resources' => $resources,
'router' => array(
'routes' => array(
'example.com' => array(
'type' => 'Zend\Mvc\Router\Http\Hostname',
'options' => array(
'route' => '[:subdomain.]:domain.:tld', // domain levels from right to left
'contraints' => array(
'subdomain' => 'www',
'domain' => 'example',
'tld' => 'com',
),
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'itdoc',
),
),
'may_terminate' => true,
'child_routes' => array(
'customCatalog2' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/custom-catalog',
'defaults' => array(
'action' => 'customCatalog',
),
),
),
When accessing http://example.com, I'm getting a 404.
But the child route works fine (http://example.com/custom-catalog)
But if I comment out the child_routes (and may_terminate), I can access the root domain
Do you have any clue of what is wrong with my code ?
Thanks !!!
I test your code and in fact this is weird, but after some test and read the docs here is what i Found.
This documentaiton help
^
I looked forward to this component and found in the docs this :
'packages.zendframework.com' => array(
'type' => 'Zend\Mvc\Router\Http\Hostname',
'options' => array(
'route' => ':4th.[:3rd.]:2nd.:1st', // domain levels from right to left
'contraints' => array(
'4th' => 'packages',
'3rd' => '.*?', // optional 3rd level domain such as .ci, .dev or .test
'2nd' => 'zendframework',
'1st' => 'com',
),
// Purposely omit default controller and action
// to let the child routes control the route match
),
// child route controllers may span multiple modules as desired
'child_routes' => array(
'index' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Package\Controller\Index',
'action' = > 'index',
),
),
'may_terminate' => true,
),
),
),
As you can see, they have child route but the first route declared is the route match this pattern : '/', this is your main route you have to declare this equal to your code below :
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'itdoc',
),
After that, your main route is correct and you can continue with other child route, just the hostname is not the actual main route '/'.
i am trying to make my router working so that:
/Auth redirects to Auth controller of Auth MOdule
/Auth/Login redirects to Login controller of Auth Module
While the first works just right the /Auth/Login results in routing issue.
My router configuration file looks like below:
'router' => array(
'routes' => array(
'Auth' => array(
'type' => 'literal',
'options' => array(
'route' => '/Auth',
'defaults' => array(
'controller' => 'Auth\Controller\Auth',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'Auth/Login' => array(
'type' => 'literal',
'options' => array(
'route' => '/Login',
'defaults' => array(
'controller' => 'Auth\Controller\Login',
'action' => 'index')
),
),
),
),
),
),
edit this section
'child_routes' => array(
'Auth_Login' => array(
// ... your existing codes
Just remove / from Auth/Login and use hyphen - or _ instead.
The answer lies in #TimFountain his comment. Because you named the child route Auth/Login you will have to request Auth/Auth/Login to get a match.
As soon as you rename the child route to Login you will get the route match as expected on Auth/Login.
I've have an problem to redirect on child routes in zend framework 2. I can access the controller and action but while redirecting it throws me an error missing parameter "id".
'admin' => array(
'type' => 'segment',
'options' => array(
'route' => '/admin[/][:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Admin',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'settings' => array(
'type' => 'Segment',
'may_terminate' => true,
'options' => array(
'route' => '/general[/][:action][/][:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Admin\Controller\Settings\General',
'action' => 'index',
),
),
),
),
),
I have given redirect to route like below,
return $this->redirect()->toRoute('admin/settings');
But it throws an error,
Missing parameter "id"
as the error message implies you need to add the "id" parameter. You can redirect with a parameter like so.
return $this->redirect()->toRoute('admin', array('action'=>'settings', 'id' => $id));
You did not show us your Controller action's but I assume 'settings' is a action within your admin module.
At this point I cannot really see what kind of id the admin/settings function need's might aswell just try to add a 0 or 1 to try the route at first for testing purposes.
The route matching method doesn't seem to 'consume' the parent node of the route.
Changing the child route to include the /admin part of the grammar to
/admin/settings/general[/][:action][/][:id]
or
/admin/settings[/][:action][/][:id]
should allow $this->redirect()->toRoute('admin/settings'); to work.
After searching a long time with no success.
before I give up, I would like to ask:
Is there a way to route a subdomain to a module in Zend Framework 2? like:
Subdomain => Module
api.site.com => api
dev.site.com => dev
admin.site.com => admin
site.com => public
...
I tried doing it like this but I can't get access to controllers other than the default (Index).
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Thank you for taking the time to help me.
Zend Framework 2 doesn't have a notion of routing to modules; all routing mappings are between a URI pattern (for HTTP routes) and a specific controller class. That said, Zend\Mvc provides an event listener (Zend\Mvc\ModuleRouteListener) which allows you to define a URI pattern that maps to multiple controllers based on a given pattern, and so emulates "module routing". To define such a route, you would place this as your routing configuration:
'router' => array(
'routes' => array(
// This defines the hostname route which forms the base
// of each "child" route
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'site.com',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
// This Segment route captures the requested controller
// and action from the URI and, through ModuleRouteListener,
// selects the correct controller class to use
'default' => array(
'type' => 'Segment',
'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(
'controller' => 'Index',
'action' => 'index',
),
),
),
),
),
),
),
(Click here to see an example of this # ZendSkeletonApplication)
This is only half of the equation, though. You must also register every controller class in your module using a specific naming format. This is also done through the same configuration file:
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController'
),
),
The array key is the alias ModuleRouteListener will use to find the right controller, and it must be in the following format:
<Namespace>\<Controller>\<Action>
The value assigned to this array key is the fully-qualified name of the controller class.
(Click here to see an example of this # ZendSkeletonApplication)
NOTE: IF you aren't using ZendSkeletonApplication, or have removed it's default Application module, you will need to register the ModuleRouteListener in one of your own modules. Click here to see an example of how ZendSkeletonApplication registers this listener
If i understand slide #39 of DASPRIDS Rounter Presentation correctly, it's as simple as - on a per module basis - to define your subdomain hosts, i.e.:
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Hostname',
'options' => array(
'route' => 'api.site.com',
'defaults' => array(
'__NAMESPACE__' => 'Api\Controller',
'controller' => 'Index',
'action' => 'index',
),
)
)
),
),
Etc, you'd do this for every Module on its own.
My Zend Framework 2 application has a route definition that's trying to mimic the default Zend Framework 1 route. It looks like:
'router' => array(
'routes' => array(
'default' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'wildcard',
),
),
),
),
),
It matches routes just fine, but I can't assemble routes with arbitrary parameters using the Url view helper.
For example,
$this->url('default', array('controller' => 'test', 'action' => 'test', 'id' => 5));
results in /test/test instead of /test/test/id/5.
Does anyone know how to assemble partial routes like this? Or is there a better way of getting ZF1-style routes?
It turns out that you need to specify the entire route name (including child routes) in the Url view helper.
Using the router defined in my question, the proper view helper call would look like:
$this->url('default/wildcard', array('controller' => 'test', 'action' => 'test', 'id' => 5));
which would result in a url of /test/test/id/5.