for example, I want to get this url string
/1/2/3/4
In view:
$this->url('routeName', array(
'a' => array(1, 2, 3, 4)
));
In controller:
print_r($this->params()->fromRoute('a'));
Output is:
array(
0 => 1,
1 => 2,
2 => 3,
3 => 4
);
Is it possible to create this route?
IF it would work at all, it'd be using the class Zend\Mvc\Router\Http\WildCard. Since I never got that one to be working the way i expected it to be though, i suggest you go the ZF2 way where you have full control over what you're doing ;) Parameters and configuration stuff should be named always! I suggest you create a simple route of type Zend\Mvc\Router\Http\Segment:
'routename' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:val1/:val2/:val3/:val4',
'defaults' => array(
'controller' => 'controllername',
'action' => 'actionname'
),
'constraints' => array(
'val1' => '[0-9]+',
'val2' => '[0-9]+',
'val3' => '[0-9]+',
'val4' => '[0-9]+'
)
)
)
If the requirements are different, obviously the route configuration would change. You'd need to set up the route like this:
$this->url('routename', array(
'val1' => 1,
'val2' => 2,
'val3' => 3,
'val4' => 4
));
Add the url routing in module.config.php file like this:
'routename' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => 'routename[/:val1][/:val2][/:val3][/:val4]',
'defaults' => array(
'controller' => 'controllername',
'action' => 'actionname'
),
'constraints' => array(
'val1' => '[0-9]+',
'val2' => '[0-9]+',
'val3' => '[0-9]+',
'val4' => '[0-9]+'
)
)
)
And then add the number by following this:
$this->url('routename', array(
'val1' => 1,
'val2' => 2,
'val3' => 3,
'val4' => 4
));
And you can get all the parameter by :
print_r($this->params());
Related
I have a problem I could not solve, I have a child route, like this:
'apps'=>array(
'type'=>'Segment',
'options'=>array(
'route' => '/apps[/[:action[/:id]]]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Apps\Controller\Index',
'action' => 'index'
),
),
'may_terminate' => true,
'child_routes' => array(
'ximages' => array(
'type' => 'Segment',
'options' => array(
'route' => '/ximages[/[:action[/:id_ximage]]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Apps\Controller\xImages',
'action' => 'index'
)
),
),
In the file .phtml I want to access the path http://miserver/apps/view/1/ximages/images/1 and what I do is the following:
echo $this->url(
'apps/ximages',
array(
'action'=>'view',
'id' => 1,
'id_ximage' => 2
)
);
But this code only prints me to the path http://miserver/apps/view/1/ximages/index/1 and do not know how you can pass the name of the action of the child route.
your route is not properly set, because your params are the same between your main route and your child route (:action)
'route' => '/apps[/[:action[/:id]]]',
'route' => '/ximages[/[:action[/:id_ximage]]]',
the first parameters is defined by what your give here :
echo $this->url(
'apps/ximages',
array(
'action'=>'view',
'id' => 1,
'id_ximage' => 2
)
);
so the view parameters is correctly set for your main route, but this params is consumed, and cannot be used again. So in the second params called with the name action you have no params given soi the default is called and for you it's
controller' => 'Apps\Controller\xImages',
'action' => 'index'
By the way, your "controller" params is useless ;)
So i advise you to change your child route params :action to anything else, and set the param in your .phtml file like the others.
'route' => '/ximages[/[:action2[/:id_ximage]]]',
echo $this->url(
'apps/ximages',
array(
'action'=>'view',
'id' => 1,
'id_ximage' => 2,
'action2' => 'images'
)
);
this is a part of my file:
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '[:controller[/:action]][/:param1]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
'action' => 'index',
'__NAMESPACE__' => 'Application\Controller',
'param1' => 'tralala'
)
)
)
)
So, instead of param1, I want to define an array, How can I do that ? When i set the keys in the array:
$this->redirect()->toRoute(null, array(
'controller' => 'user',
'action' => 'confirm',
'param1' => array(
'email'=>$request->getPost('mail'),
'name'=>$request->getPost('name')
)
));
and accessing it :
$params = $this->params()->fromRoute('param1');
var_dump($params); exit();
Obviously my code does not work. It is possible to set an array in the route, or I'm asking stupid thing s here ? thx
I have the following route in my module.config.php:
'routes' => array(
'admin' => array(
'type' => 'Segment',
'options' => array(
'route' => '/admin[/:controller[/:action]][/]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'__NAMESPACE__' => 'Admin\Controller',
'module' => 'Admin',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'Wildcard',
)
),
'priority' => 1000
),
),
The reason for the [/] in the end of the route is in the question: Zend Framework 2 Segment Route matching 'test' but not 'test/'
I want this route to be like in ZF1. I want to pass $_GET parameters in it (like /id/1/test/2/).
The problem it this route is actually matching /admin/customer/edit//id/20 but not matching /admin/customer/edit/id/20
Any ideas?
You are on the right track! Use "Wilcard" as a type of child-route to your admin-route.
There are two options available: key_value_delimiter and param_delimiter.
Both's default values are '/' which is equal to the ZF1 default behaviour of route parameters.
'router' => array(
'routes' => array(
'admin' => array(
'type' => 'Segment',
'options' => array(
'route' => '/admin[/:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
),
'defaults' => array(
'__NAMESPACE__' => 'Admin\Controller',
'module' => 'Admin',
'controller' => 'Index',
'action' => 'index',
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'Wildcard',
'options' => array(
'key_value_delimiter' => '/',
'param_delimiter' => '/'
)
)
)
)
)
)
If you want to address the wildcard route with the help of the url view-helper, you can use it like that:
$this->url('admin/wildcard', array('id' => 1234, 'foo' => 'bar'));
You can add route parameter for id :
'route' => '/admin[/:controller[/:action]][/:id][/]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
'id' => '[0-9]+',
),
this route matchs admin/customer/edit/20/, so you can get id in controller:
$this->params()->fromRoute('id');
If you want to have admin/customer/edit/id/20/ ,try:
'route' => '/admin[/:controller[/:action]][id/:id][/]',
If I am understanding correctly, you are trying to get multiple parameters from the URL, right?
e.g.
Traditional GET: www.domain.com/ctrl/action?key1=abc&key2=efg& ... & keyN=xyz
ZF2 route: www.domain.com/ctrl/action/key1/abc/key2/efg/.../keyN/xyz
If so, this is one way of doing it:
'adminPage' => array(
'type' => 'regex',
'options' => array(
'regex' => '/admin/customer/edit[/](?<keyValuePairs>.*)',
'defaults' => array(
'controller' => 'YourProject\Controller\YourController',
'action' => 'yourAction',
),
'spec' => '/admin/customer/edit/%keyValuePairs%',
)
With this, every character after 'admin/customer/edit/' will be stored in 'keyValuePairs' parameter. In Controller::yourAction, get the 'keyValuePairs' parameter, then split the string back into a meaningful key-value data structure.
I'm newbie in ZF2, but I try to write an application. And I faced a problem with invokables and routing config.
I have 2 modules with configs:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Index' => 'Vocabulary\Controller\IndexController'
,'Add' => 'Vocabulary\Controller\AddController'
,'Admin' => 'Vocabulary\Controller\AdminController'
)
)
,'router' => array(
'routes' => array(
'vocabulary' => array(
'type' => 'segment'
,'options' => array(
'route' => '/vocabulary[/: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'
)
)
)
)
)
and
<?php
return array(
'controllers' => array(
'invokables' => array(
'Admin' => 'Lang\Controller\AdminController'
,'Translation' => 'Lang\Controller\TranslationController'
)
)
,'router' => array(
'routes' => array(
'lang' => array(
'type' => 'segment'
,'options' => array(
'route' => '/lang[/:controller][/:action]'
,'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*'
,'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
)
,'defaults' => array(
'controller' => 'Admin'
,'action' => 'index'
)
)
)
)
)
But on page /vocabulary/admin I see content of page /lang/admin. It seems, that problem is that invokable array's keys "Admin" are equal.
How can I modify my config to make application work correctly? I want to keep "lang/admin" and "vocabulary/admin" paths.
I tried to use "Vocabulary\Controller\Admin" instead of "Admin" as invokable key, but it didn't help.
UPDATE
I solved the problem using this variant of configuration (I hope it will be helpful for somebody):
return array(
'controllers' => array(
'invokables' => array(
'Lang\Controller\Admin' => 'Lang\Controller\AdminController'
,'Lang\Controller\Translation' => 'Lang\Controller\TranslationController'
)
)
,'router' => array(
'routes' => array(
'lang' => array(
'type' => 'Literal'
,'options' => array(
'route' => '/lang'
,'defaults' => array(
'__NAMESPACE__' => 'Lang\Controller',
'controller' => 'Lang\Controller\Admin'
,'action' => 'index'
)
),
'may_terminate' => true,
'child_routes' => array(
'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(
),
),
),
),
)
)
)
In this case view helper command $this->url('lang', array('controller' => 'translation')) returns only "lang/", but I use $this->serverUrl('/lang/translation');
Both of modules work correctly.
You could simply define your invokables and routes using the full namespace as in
'controllers' => array(
'invokables' => array(
'Vocabulary\Controller\Index' => 'Vocabulary\Controller\IndexController'
,'Vocabulary\Controller\Add' => 'Vocabulary\Controller\AddController'
,'Vocabulary\Controller\Admin' => 'Vocabulary\Controller\AdminController'
)
)
and
'controllers' => array(
'invokables' => array(
'Lang\Controller\Admin' => 'Lang\Controller\AdminController'
,'Lang\Controller\Translation' => 'Lang\Controller\TranslationController'
)
)
and then adjust your defaults keys for each routing section to have the new key with the full namespace. i.e.
'defaults' => array(
'controller' => 'Lang\Controller\Admin'
,'action' => 'index'
)
It's a personal preference to include the full namespace, as it makes it clearer to me where my code is pointing to. You don't have to do that, but the invokables for your controllers cannot be duplicated as this config is merged into one large config array with the last one defined winning. So your definition for the invokable key Admin as the Lang\Controller\AdminController overwrites your earlier assignment of that key to Vocabulary\Controller\AdminController.
To answer the last part of your question (as I agree with #ChanlderTi on the first part) :
In this case view helper command $this->url('lang', array('controller' => 'translation')) returns only "lang/"
This is because the "lang" route is a literal defining only "lang/". What you're trying to do is define the child route's url, whose full route name is "lang/default". So your code should be :
$this->url('lang/default', array('controller' => 'translation'))
You should probably define a default action for the child route also. Although I don't remember if the Router will default to index if no action is specified.
I'm trying to reuse query params using Url helper in a view. This is my current url:
http://localhost/events/index?__orderby=name&__order=asc
I'm using this code in the view:
$this->url('events/index', array('__page' => '2'), true);
I want to obtain this url:
http://localhost/events/index?__orderby=name&__order=asc&__page=2
But instead i get this:
http://localhost/events/index?controller=Application\Controller\Events&__page=2
This is my route inside module.config.php file:
'events' => array(
'type' => 'segment',
'options' => array(
'route' => '/eventos[/:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'Application\Controller\Events',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'index' => array(
'type' => 'Query',
),
),
),
What am i doing wrong? Thanks for your help.
I think what you are looking for is a Query route type to capture the Query string for you as a child route:
'route' => array(
'type' => 'literal',
'options' => array(
'route' => 'page',
'defaults' => array(
),
),
'may_terminate' => true,
'child_routes' => array(
'query' => array(
'type' => 'Query',
'options' => array(
'defaults' => array(
'foo' => 'bar'
)
)
),
),
You can then use the view helper to generate and append the query string for you. If you don't use a Query child route, then the helper will just ignore your query string.
$this->url(
'page/query',
array(
'name'=>'my-test-page',
'format' => 'rss',
'limit' => 10,
)
);
You can then set the third parameter to TRUE and allow the helper to use the current parameters as you are trying to do in your example.
There's examples in the docs:
http://framework.zend.com/manual/2.0/en/modules/zend.mvc.routing.html
You could use something like this, but the query parameters arent reused in my case.
$this->url(
'page/query',
array(),
array(
'query' => array(
'name'=>'my-test-page',
'format' => 'rss',
'limit' => 10,
)
),
true
);
So if you want to reuse query parameters you coul merge them with your new ones and then add all of them to the query array (3 parameter).