Stopping zend route default paramaters 'key' displaying in the URL - zend-framework

I have a route defined as below.
$route['manage-vehicles'] = new Zend_Controller_Router_Route(
'vehicles/manage/page/:page',
array(
'controller' => 'vehicles',
'action' => 'manage',
'page' => '1'
)
);
When the 'page' parameter is not specifically defined (e.g. in a menu constructed using the navigation component), the resultant URL is
/vehicles/manage/page
I would much prefer or the URL not to to display the default paramater key in this scenario
i.e. /vehicles/manage
Any ideas how to accomplish this would be appreciated?
Thanks.
EDIT: For clarity, I would like vehicles/manage/page/1 etc to display when the 'page' parameter is defined

The 'page' string you have in your route is not required for the page parameter to work, so all you need to do is change your route to:
$route['manage-vehicles'] = new Zend_Controller_Router_Route(
'vehicles/manage/:page',
array(
'controller' => 'vehicles',
'action' => 'manage',
'page' => '1'
)
);
you've told it which thing in the URL is 'page', so you don't need the prefix there. That's just part of the default route where the parameters are not predefined.

Related

Zend routes two routes need same count of params

I don´t know what I do wrong. I got two named Zend route:
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:productIdent/',
array(
'action' => 'viewproduct',
'controller' => 'catalog',
'module' => 'eshop',
'categoryIdent' => '',
'productIdent' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+',
'productIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category_product', $route);
// catalog category route
$route = new Zend_Controller_Router_Route(
'catalog/:categoryIdent/:page/',
array(
'action' => 'viewcategory',
'controller' => 'category',
'module' => 'eshop',
'categoryIdent' => '',
'page' => ''
),
array(
'categoryIdent' => '[a-zA-Z-_0-9]+'
)
);
$router->addRoute('catalog_category', $route);
When I call catalog_category its all fine but when I try call to catalog_category_product is used viewcategory action from second route. It means its problem with :page variable in url, resp. same count of arguments in URL? I think that itsn´t nessesary I would like to get two different but similar routes - for example:
For category - catalog/category1/1
For product - catalog/category1/product1 (without number of page)
when I change form of route catalog_category_product to catalog/:categoryIdent/something/:productIdent/ so its working
here is route calls
$this->url(array('categoryIdent' => categoryIdent, 'productIdent' => productIdent), 'catalog_category_product', true);
$this->url(array('categoryIdent' => 'cerveny-cedr', 'page' => 'pageNumber'), 'catalog_category', true);
Thanks for any help
Keep in mind that routes are checked in reverse order, so the ZF router will check the catalog_category route before the catalog_category_product route when matching URLs. So, the number of arguments is not a problem, but since you've not put any sort of restriction on the 'page' parameter, all URLs that would normally match your catalog_category_product URL will be matched by catalog_category instead.
It sounds like 'page' should be numeric, so adding that restriction to your second route should fix the problem.

Zend Framework: Route assemble and GET parameters

In my Bootstrap I have
$route = new Zend_Controller_Router_Route(
':language/:country/:controller/:action/*',
array(
'language' => 'en',
'country' => 'us',
'controller' => 'bicycle',
'action' => 'index'
),
array(
'language' => '[a-z][a-z]',
'country' => '[a-z][a-z]'
)
);
Somewhere in my view I have
echo $this->url(array('page'=>2));
//actually this translated to $route->assemble(array('page' => 2), null, false);
The problem, is when I have some GET parameters: they won't be considered in the building of the link, and this is what I actually want.
Example:
I access the URL (in the browser)
http://localhost/myproject/en/us/controller/action/?get1=gval1&get2=gval2&get3=gval3
and the assembled URL is
http://localhost/myproject/en/us/controller/action/page/2
INSTEAD of
http://localhost/myproject/en/us/controller/action/page/2/get1/gval1/get2/gval2/get3/gval3/
or (I would prefer the next one)
http://localhost/myproject/en/us/controller/action/page/2/?get1=gval1&get2=gval2&get3=gval3
Any ideas?
Of course one solution (with Apache) would be to call this in my view:
$this->url(array(page=>2)) . ($_SERVER['QUERY_STRING']?$_SERVER['QUERY_STRING']:"")
but you cannot be sure this will always be included in the $_SERVER variable.

Custom route with parameters

I want to make customer route for url which have parameters.
<a href='javascript:void(0)' onclick="window.location='<?php echo
$this->url(array('module' => 'courses', 'controller' => 'course', 'action' => 'add',
'std_id' => $entry['std_id']), 'coursesadd', TRUE); ?>'">add course</a>
and here what I make routing
$route = new Zend_Controller_Router_Route('courses/std_id/:std_id',
array('module' => 'courses', 'controller' => 'course', 'action' => 'add'));
$routesArray = array('coursesadd' => $route );
$router->addRoutes($routesArray);
But It doesn't route correctly!
Your code looks fine, except what RockyFord sad - You should only pass these parameters to url() helper which are required by designated route (when 'default' route is used indeed it requires module, controller, action, but Your 'coursesadd' route requires only std_id parameter). Moreover You should improve Your route a little bit to:
$route = new Zend_Controller_Router_Route('courses/:std_id', array(
'module' => 'main',
'controller' => 'product',
'action' => 'add',
'std_id' => null //default value if param is not passed
));
The param_name/:param_value construction in Your route is redundant because You already named the parameter, so by using above route You'll get std_id param in controller using
$this->_getParam('std_id')
Default value in route definition would save from throwing Zend_Controller_Router_Exception: std_id is not specified but it looks like $entry['std_id'] is not set.

Zend Routing problems

I've read all posts about routing and Zend Documentation but I still can't solve this issue.
I have a multi-language application with two modules: default and admin. The language selection is working fine (in a Controller routeShutdown Plugin), but I have some problems configuring the router:
I want to have these URL working:
/
/controller
/controller/action
/action (default controller)
/controller/param (default action)
/admin
/admin/admin-controller
/admin/admin-controller/action
and using the language selector it would be:
/en
/en/controller
/en/controller/action
/en/action (default controller)
/en/controller/param (default action)
/en/admin/admin-controller
/en/admin/admin-controller/action
I added this to my bootstap file (index.php):
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->removeDefaultRoutes();
$router->addRoute('langmodcontrolleraction',
new Zend_Controller_Router_Route('/:lang/:module/:controller/:action',
array('lang' => ':lang'))
);
$router->addRoute('langmodcontroller',
new Zend_Controller_Router_Route('/:lang/:module/:controller',
array('lang' => ':lang',
'action' => 'index'))
);
$router->addRoute('langmod',
new Zend_Controller_Router_Route('/:lang/:module',
array('lang' => ':lang',
'action' => 'index',
'controller' => 'index'))
);
$router->addRoute('lang',
new Zend_Controller_Router_Route('/:lang',
array('lang' => ':lang',
'action' => 'index',
'controller' => 'index',
'module' => 'default'))
);
$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers',
'admin'=>BASE_PATH.'app/modules/admin/controllers'));
In order to check how the router is parsing the URL, I added a var_dump to the routeShutdown plugin:
Entering to /en, I get:
array
'lang' => string 'en' (length=2)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
'module' => string 'default' (length=7)
which is OK. But when I enter to /en/controller1 I get:
array
'lang' => string 'en' (length=2)
'module' => string 'controller1' (length=8)
'action' => string 'index' (length=5)
'controller' => string 'index' (length=5)
It is setting module to "controller1". How can I tell the router to set the default value to the module? And for an URL like /en/controller/param? (setting module and action to default)
I'm afraid you're going to need to rethink your URL scheme a little, or change the way your routes are setup, as you've hit two limitations of the way ZF's routing works.
The first is that the router has no knowledge of what is or isn't a valid module, controller or action; all it does is match the strings in the URL to variables in the route. It does this by checking each route in succession, in reverse order, until it finds a match. When you hit /en/controller, it first checks your /:lang route, which won't match. It then checks /:lang/:module, which will match, because /:lang/:module will match /anything/anything unless you tell it otherwise.
With that in mind you won't be able to have both:
/en/controller
/en/action
unless you set some restrictions, as a URL like /en/foo will always be matched by whichever of the two you define last.
If you have a fairly small number of actions/controllers that don't often change, the simplest way around this is to hardcode in some possible values for the 2nd of the two routes, e.g.:
$router->addRoute('langmod', new Zend_Controller_Router_Route(
'/:lang/:module',
array(
'lang' => ':lang',
'action' => 'index',
'controller' => 'index'
),
array(
'module' => '(foo|bar|something)'
)
));
replace foo, bar etc. with valid module names. Now when you hit /en/controller1 it won't match this route because controller1 doesn't match the regexp pattern defined for the :module variable. You would then need a separate /:lang/:controller route (or possibly /:lang/:controller/:action) for it to match instead.
You asked how you set a default value for some of the variables. You are actually already doing this with the action in a few of your routes, but for controller/module won't quite work in the way you are hoping. If we take your langmodcontroller route and change it to this:
$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
'/:lang/:module/:controller',
array(
'lang' => ':lang',
'controller' => 'index'
'action' => 'index'
)
));
there's now a default value for the controller variable. If we pretend for a second that this was the only route, a request for /en/blog would now get matched by this and set the request params to lang = en, module = blog, controller = index, action = index. /en/blog/index/foo would also match this route, and would give you module = blog, controller = index, action = foo. But note that even though controller = index you still need that in the URL. So limitation number two is that you always need the variable in the URL (even if it is set to your default) as long as you have something after it that isn't the default.
With these limitations in mind I'd suggest you go with something like this (defined in this order):
/:lang/:controller/:action/ (with 'index' defaults for controller and action)
/:lang/:action (with 'action' restricted to some predefined values)
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default)
This would give you URLs like this:
/en
/en/controller
/en/controller/action
/en/action
/en/controller/param
/en/admin/controller
/en/admin/controller/action
which is pretty much what you are after.
The routing in ZF is very powerful, you just need to know its quirks.

Zend Framework Router Getting /module/VALUE/controller/action

I've been googling around and I can't seem to find anything which explains the use of ZF router well. I've read the documentation on the site, which seems to only talk about re-routing.
I am trying to make the format:
/module/value/controller/action give /module/controller/action passing on value as a parameter
e.g.
/store/johnsmithbigsale/home/newstuff would route to /store/home/newstuff passing on johnsmithbigsale as the value to a parameter with a hidden namespace e.g. storeName.
Some help would be greatful!
You can use Zend_Controller_Router_Route to map your url parts to modules, controllers, actions, and parameters that can be used in the controller by $this->_getParam('varName'). You can define these routes in the application.ini file or in the application bootstrap.
// custom city route
$route = new Zend_Controller_Router_Route(
'cities/:city',
array(
'controller' => 'city',
'action' => 'view'
)
);
$this->addRoute('city', $route);
// custom buy widgets route
$route = new Zend_Controller_Router_Route_Regex(
'buy_(.+)_widgets/([0-9]+)(.*)',
array(
'controller' => 'widgets',
'action' => 'view'
),
array(
1 => 'nothing',
2 => 'widget_id',
3 => 'vars'
)
);
$this->addRoute('widgets', $route);
The regex route is kind of specific to my app, but you can see that each match can get mapped to a parameter.