I am trying to get some basic routing done in ZF2 but I am running into some problems.
The section that is giving me trouble is this:
'parent-categories' => array(
'type' => 'literal',
'options' => array(
'route' => '/kategorier/',
'defaults' => array(
'controller' => 'categories',
'action' => 'parent-categories',
),
),
'may_terminate' => true,
'child_routes' => array(
'child-categories' => array(
'type' => 'segment',
'options' => array(
'route' => '/kategorier[/:slug][/:parentCategoryid]/',
'constraints' => array(
'parentCategoryid' => '[0-9]+',
),
'defaults' => array(
'controller' => 'categories',
'action' => 'child-categories',
)
),
),
),
),
The original 'parent-categories' route works just fine, no problem. The problem though is the child-categories route isn't doing anything. I have the URL:
/kategorier/test-test-test-test-test/1/
but this is never matched to anything. I get the error:
The requested URL could not be matched by routing.
If I take the child-categories route out of the "child_routes" section, it always catches the request, even if the url is only /kategorier/. Can anyone see what I am doing wrong here?
A child route appends to the parent route. I.e. what you're currently matching is
/kategorier//kategorier[/:slug][/:parentCategoryid]/
Do it like this
'parent-categories' => array(
'type' => 'literal',
'options' => array(
'route' => '/kategorier',
'defaults' => array(
'controller' => 'categories',
'action' => 'parent-categories',
),
),
'may_terminate' => true,
'child_routes' => array(
'child-categories' => array(
'type' => 'segment',
'options' => array(
'route' => '[/:slug][/:parentCategoryid]',
'constraints' => array(
'parentCategoryid' => '[0-9]+',
),
'defaults' => array(
'controller' => 'categories',
'action' => 'child-categories',
)
),
),
),
),
And i guess this should be working out alright. It's a good advice to NOT have trailing slashes, as you'd ideally always want to begin new routes with one for better readability ;)
Related
I'm having and issue with the view helper function this->url() that doesn't return and url from a child route and I get a White Screen of the dead. When I put the url manually in the browser the router recognizes the url well.
I have this in my module.config.php:
'news' => array(
'type' => 'Segment',
'options' => array(
'route' => '/news[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Application\Controller\News',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'allnews' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:action[/:tab[/:page]]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'tab' => '[0-9]+',
'page' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Application\Controller\News',
'action' => 'all',
'tab' => 1,
'page' => 1,
),
),
),
),
),
For example:
/news/2
Works correctly and matches the parent route
And:
/news/all/2/5
Works correctly and matches the child route.
But when I use this in the view-helper I get a White Screen of the Dead:
echo($this->url('news/allnews', array('action' => 'all', 'tab' => '1', 'page' => '1')));
My question is: What it's wrong?? I used this method in others views and worked well.
You do not need to use child routes in combination with Router Segments. One Segment should be sufficient!
'news' => array(
'type' => 'Segment',
'options' => array(
'route' => '/news[/:action[/:id][/:tab][/:page]]',
'constraints' => array(
'id' => '[0-9]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'tab' => '[0-9]+',
'page' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Application\Controller\News',
'action' => 'index',
),
),
),
As long as the Defaultcontroller is sufficient you for your needs you also would not need to have it within your params. Once you need more then 1 you prob want to have another constraint defining the controller.
Now you could simply use the url viewhelper in various ways.
if you only need the default action within your default controller you could write it like so.
$this->url('news');
If you need to route to actions with params you could use the viewhelper like so
$this->url('news', array('action' => $action, 'tab' => $tab, 'page' => $page));
Ideally I would use a Router Literal with Router Segments as child routes since bombarding the router segment with tons of constraints gets messy pretty fast.
...
'custom_route' => array(
'type' => 'Literal',
'priority' => 1337,
'options' => array(
'route' => '/custom',
'defaults' => array(
'__NAMESPACE__' => 'Custom\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'custom_child' => 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(
),
),
),
),
),
...
Pretty sure this won't help but everything does look right in your routing... Have you tried
$this->url('news/allnews', array('action' => 'all', 'tab' => 1, 'page' => 1))
Don't know how the routing stuff handles contraints on digits and providing strings to url view helper.
You probably either need to enable errors or look in the log to find out the actually error
I want add crm as prefix of CRM module.
This is router section in my module.config.php
'router' => array(
'routes' => array(
'calendar' => array(
'type' => 'segment',
'options' => array(
'route' => '/crm/calendar[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Crm\Controller\Calendar',
'action' => 'index',
),
),
),
When i use test.dev/crm/calendar/index is working properly. But it is not working for test.dev/crm/calendar . I couldn't find any issue.
When i use 'route' => '/calendar[/:action][/:id]', i can use test.dev/calendar. But i need use prefix. How can i do it?
I think it might be that you have to add 'may_terminate' => true,
So your route definition will look like this:
'calendar' => array(
'type' => 'segment',
'options' => array(
'route' => '/crm/calendar[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Crm\Controller\Calendar',
'action' => 'index',
),
),
'may_terminate' => true,
),
Try if that works.
Otherwise you can also split it and make crm to a literal route.
'crm' => array(
'type' => 'literal',
'options' => array(
'route' => '/crm',
),
'may_terminate' => false,
'child_routes' => array(
'calendar' => array(
'type' => 'segment',
'options' => array(
'route' => '/calendar[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Crm\Controller\Calendar',
'action' => 'index',
),
),
),
),
),
But this last solution means that you will always have to route to crm/calendar
As seen configs should correct.
Did you tried without last / (test.dev/crm/calendar, not test.dev/crm/calendar/)
Route configuration is correct. This route had over write from another module route. That's the issue. ZF2 has not easy way to check all routes and paths.
what do I need to write in the module.config file to accept a route in the folowing format?
/action/parameter/value
I think in ZF1 this was done by default
Thank you
Here Is my route, I tried but I just can't get it to work
what route I need is classes/less/value
where less is a query parameter
'classes' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:lang/classes',
'defaults' => array(
'__NAMESPACE__' => 'Classes\Controller',
'controller' => 'Classes',
'action' => 'index',
'lang' => 'en',
),
),
'may_terminate' => true,
'child_routes' => array(
'process' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'lang' => '[a-z]{2}',
),
'defaults' => array(
),
),
),
),
),
To help you more, we will need to see your current routing.
You will basically need a simple segment route with your action, followed by an open wildcard non required section:
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/products[/:action]',
'defaults' => array(
'controller' => 'Application\Controller\Products',
'action' => 'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'Wildcard'
)
)
)
If I understand correctly you would like your route to contain a parameter. The way i updated your code below you are able to add one more constraint in your route. So it is action/less/lang. Consider the updated code below assuming i understood what you are trying to do.
'classes' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:lang/classes',
'defaults' => array(
'__NAMESPACE__' => 'Classes\Controller',
'controller' => 'Classes',
'action' => 'index',
'lang' => 'en',
),
),
'may_terminate' => true,
'child_routes' => array(
'process' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'less' => '[a-zA-Z0-9_-]*',//edit here
'lang' => '[a-z]{2}',
),
'defaults' => array(
),
),
),
),
),
i have defined two routes, /shoppingcart/ and a child route /shoppingcart/add/ which should only be available for POST requests.
'routes' => array(
'shoppingcart' => array(
'type' => 'literal',
'options' => array(
'route' => '/shoppingcart/',
'defaults' => array(
'controller' => 'ShoppingcartController',
'action' => 'shoppingcart',
),
),
'may_terminate' => true,
'child_routes' => array (
'add-product' => array(
'type' => 'method',
'options' => array(
'verb' => 'post',
'route' => 'add/',
'defaults' => array(
'controller' => 'ShoppingcartController',
'action' => 'addProductToShoppingcart',
),
),
),
)
),
)
The route /shoppingcart/ works fine. The child route /shoppingcart/add/ does not work(404 error with POST and GET).
When i change the type from method to literal and remove the verb key it works.
How can i use Zend\Mvc\Router\Http\Method in the child route?
You need to set may_terminate true for your child route.
Also, you mention route failing for GET, which it will if you only set the verb to post, if you want to allow get too, the verb should be get,post
Edit: after a little experimenting, it turns out my understanding was wrong, the Method type needs to be placed as parent of the route it's protecting....
'routes' => array(
'shoppingcart' => array(
'type' => 'literal',
'options' => array(
'route' => '/shoppingcart/',
'defaults' => array(
'controller' => 'ShoppingcartController',
'action' => 'shoppingcart',
),
),
'may_terminate' => true,
'child_routes' => array (
'add-product' => array(
'type' => 'method',
'options' => array(
'verb' => 'get,post',
),
'child_routes' => array(
// actual route is a child of the method
'form' => array(
'may_terminate' => true,
'type' => 'literal',
'options' => array(
'route' => 'add/',
'defaults' => array(
'controller' => 'ShoppingcartController',
'action' => 'addProductToShoppingcart',
),
),
),
),
),
),
),
),
i have a router test/view and i would like to pass some params like test/view/id/123.
Im not sure how to add those params in the zf2 router.
'router' => array(
'routes' => array(
'test' => array(
'type' => 'Literal',
'options' => array(
'route' => '/test',
'defaults' => array(
'__NAMESPACE__' => 'test\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'view' => array(
'type' => 'Literal',
'options' => array(
'route' => '/view',
'defaults' => array(
'controller' => 'Index',
'action' => 'view',
),
),
),
),
),
),
),
i setup view as a child route but not sure where to add those params.
i've tried 'route' => '/view/:id/:value' and
'defaults' => array(
'controller' => 'Index',
'action' => 'view',
'id' => 'value',
)
but they don't seem to work
i am trying to understand how all this works.
any ideas? thanks
'router' => array(
'routes' => array(
'test-view' => array(
'type' => 'segment',
'options' => array(
'route' => '/test/view/:testId[/]',
'constraints' => array(
'testId' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Test\Controller\Index',
'action' => 'view'
),
),
),
In your ControllerAction you can then get the parameter "testId" by using:
$this->params('testId');
Btw: The above route gives you an url like this: /test/view/123 - I thought you may get rid of the "id" param.
If you want to create a link to one kind of this pages, you can use $this->url('test-view', array('testId' => 123)) in one of your views.