I have never been any good at regular expressions. I am trying to use them in building a simple site. I construct a URL just fine like /some-course/some-vtm-1, but when it tries to lookup the defined controller, it fails. Here is the route I have defined:
chapter' => array(
'type' => 'Zend_Controller_Router_Route_Regex',
'route' => '/:course/:vtm\-(\d+)',
'defaults' => array(
'module' => 'learn',
'controller' => 'chapter',
'action' => 'index'
),
'map' => array(
1 => 'course',
2 => 'vtm',
3 => 'id'
),
'reverse' => '%s/%s-%d/'
),
How should I correct this Regex so it finds the correct module/controller/action when I a link like /some-course/some-vtm-1 is clicked
Your problem is that you're trying to mix the syntax of Zend_Controller_Router_Route (named variables in the route starting with :) and Zend_Controller_Router_Route_Regex (bracketed regular expression patterns in the route). You want to drop the former and just use the regexp syntax, leaving you with something like this:
array(
'type' => 'Zend_Controller_Router_Route_Regex',
'route' => '([\w]+)/(vtm)-([\d]+)',
'defaults' => array(
'module' => 'learn',
'controller' => 'chapter',
'action' => 'index'
),
'map' => array(
1 => 'course',
2 => 'vtm',
3 => 'id'
),
'reverse' => '%s/%s-%d'
),
Related
I try to validate a route in zend framework 2.
Example:
valid - /foo/overview/1-2015
valid - /foo/overview/9999-2015
invalid /foo/overview/sd-2015
invalid - /foo/overview/10001-2015
I tried this code, but I received 404 error:
'overview' => array(
'type' => 'segment',
'options' => array(
'route' => '/foo/overview/:nr',
'constraints' => array('nr' => '^[0-9]{1,4}-[0-9]{4}$',),
'defaults' => array(
'controller' => 'Foo\Controller\Foo',
'action' => 'overview',
),
),
),
thanks
It is enough to use [0-9]{1,4}-[0-9]{4} for your constraint value, since the starting ^ and the closing $ are automatically added by the framework (check the match function in the Zend\Mvc\Router\Http\Segment class).
I created the following routes:
'relatorios' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/relatorios/:tipo',
'defaults' => array(
'controller' => 'Relatorios',
'action' => 'index',
'tipo' => 'normais',
),
'constraints' => array('tipo' => '(normais|administrativos)$',
),
'may_terminate' => true,
'child_routes' => array(
'view' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/view/:id_relatorio',
'defaults' => array('action' => 'view'),
'constraints' => array('id_relatorio' => '[0-9]+'),
),
),
),
);
This is supposed to match the following routes:
/relatorios/normais //matches
/relatorios/administrativos //matches
/relatorios/normais/view/1 //doesn't match
/relatorios/administrativos/view/1 //doesn't match
So basically the :tipo parameter must be either normais or administrativos and there is a child /view/any_digits.
When the parent route is called it matches, when the child view is called it doesn't match because of my tipo constraint. Why is that?
As per my comment, the $ on the constraint means 'end of the string' (which in this case is the URL path), so it shouldn't be there.
I am struggling with regex routing....
The following urls should be valid:
/shop/api/list
/shop/api/cart
/shop/api/login
/shop/api/details/0123456789
And the details url, the last one, is not really cooperating with the following route:
'child_routes' => array(
'angularlist' => array(
'type' => 'Regex',
'options' => array(
'regex' => '/api/(?<page>login|cart|list|details(?<id>\/[0-9]+))',
'spec' => '/api/%page%[/:%id%]',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
//'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => 'list',
// 'param' => '[0-9]',
),
/* todo ipv elke child toe te voegen 'route' => '/api/[:action]', 'constraints' => array(
'action' => 'list|details|login|dashboard'
)*/
),
),
)
Instead of struggling with less-readable & dirty regex hacks, you can easily implement a Segment route stack like below:
'shop' => array(
'type' => 'Segment',
'options' => array(
'route' => '/shop/api',
'defaults' => array(
'__NAMESPACE__' => 'Shop\Controller',
'controller' => 'Api',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'angularlist' => array(
'type' => 'Segment',
'options' => array(
'route' => '/:action[/:id]', // id is optional
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'action' => 'index',
),
),
),
)
Based on this stackoverflow question 15077075 i have accomplished that my application has a regex based route so i can pass this to my view and edit action.
app/123 - app controller view action (get by article id)
app/name-of-article - app controller view action (get by article name)
app/123/edit - app controller edit action (article id)
app/name-of-article/edit - app controller edit action (article name)
app/search/{search-string} - app controler search action (currently only accepts a searchstring without spaces and special characters)
This i have accomplished with the code below and is similar to the code in the link above:
'app' => array(
'type' => 'literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
'priority' => -1000,
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
'priority' => -1000,
),
I have twoone issue
the first is that the url viewhelper doesn't recognize my routes
$controller = app
$action = recent
$this->url( $controller, array( 'action' => $action ) )
it just prints /app instead of /app/recent,
The same occurs when $action = 'search' or $action = 'new' it only prints /app
the second is that the search is recognized to its controller action only it fails when i put spaces or special characters in it
when i try to add \s in the constraints of the searchkey ( '[\sa-zA-Z0-9_-]+' ) it routes to the edit function
the route of search looks like this
Edited the route to this and it worked
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[a-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
),
),
),
i hope it's clear what i want if any code snippits are needed please ask
Sorted it out!
If one needs to get routes in his application this way you can use the code below
/App App/Index
/App/name-of-article App/View
/App/123 App/View
/App/name-of-article/edit App/Edit
/App/123/edit App/Edit
/App/recent App/Recent
/App/search App/Search
/App/new App/New
In my module.config.php i changed the route to:
'app' => array(
'type' => 'segment',
'options' => array(
'route' => '/app[/:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'priority' => 1,
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[\sa-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
'priority' => 2,
'may_terminate' => true,
),
),
),
'new' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/new',
'defaults' => array(
'controller' => 'App',
'action' => 'recent',
),
),
'priority' => 2,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
),
If you need other routes you can just add a new literal route below te app route, make sure you don't forget to set the priority
I have been trying to shortern this route:
http://abc.localhost/user/view/index/id/1
to this:
http://abc.localhost/user/1
with the following portion of code in my bootstrap but I keep getting an error stating that the 'Reversed route is not specified', any ideas why?
$route = new Zend_Controller_Router_Route_Regex(
'user/(\d+)',
array(
'module' => 'user',
'controller' => 'view',
'action' => 'index'
),
array(
1 => 'id'
)
);
$router->addRoute('user', $route);
Thanks,
Martin
If you want to use the URL helper with Regex routes you need to pass a 4th parameter to Zend_Controller_Router_Route_Regex that it can use to rebuild the route. This 4th parameter should be a string in a sprintf-format which it can inject the params into.
In your case it would be something like:
$route = new Zend_Controller_Router_Route_Regex(
'user/(\d+)',
array(
'module' => 'user',
'controller' => 'view',
'action' => 'index'
),
array(
1 => 'id'
),
'user/%d'
);
$router->addRoute('user', $route);
There is some info on this right at the end of the manual section on Regex routes: http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.regex - but it's easy to miss.