Zend Framework: Router - zend-framework

That is my two routers:
->addRoute('viewTextMaterial', new Zend_Controller_Router_Route(':mCat/:mCatSub/:mId/:mTitle', array('controller' => 'index', 'action' => 'viewtextmaterial')))
->addRoute('viewNews', new Zend_Controller_Router_Route(':nCat/:nId/:nTitle/:page', array('controller' => 'index', 'action' => 'viewnews')))
In index.phtml file I add this:
Test
Exp. for viewnews URL:
some text
But why, when I click a href, it redirect me to 'viewnews'?

In my experience(which is not very great :) )
I think when you use the colon in front of a name, when you are defining a router
i.e like
'/:mCat/:mCatSub/:mId/:mTitle',
array(
'controller' => 'index',
'action' => 'viewtextmaterial'
)
What you are telling the router to do is to route any url, which follows the above format('/:mCat/:mCatSub/:mId/:mTitle'), to be routed to the controller/action you mentioned there. eg.
someController/action/x/y
or
anoCont/act/a/b
would be routed to the same controller/action.
So in your case what you are doing is you are defining two routers with same options(which creates ambiguity), and by default the second defined route is used(Bottom to top matching).
you can use something like this
'/test/:mCatSub/:mId/:mTitle',
array(
'controller' => 'index',
'action' => 'viewtextmaterial'
)
so anything that starts with 'test' as controller(in the url) would now be routed to your desired controller/view.
Hope it works.. :) (If it doesn't please enlighten me :) )

Related

Multiple Routes with Standard Router (Zend Framework)

I am trying to set up multiple routes to the same controller in zend as such:
URL | Controller::Action
=================================================================================
http://mysite/tasks/:level/ | Objectives::Objectives
http://mysite/tasks/:level/:objective/ | Objectives::tasks
http://mysite/tasks/:level/:objective/:taskID/ | Objectives::view
I've tried the following:
<?php
$router->addRoute('objectives', new Zend_Controller_Router_Route(
'task/:level/:objective/:taskID/',
array(
'controller' => 'objectives',
'action' => 'view'
)
));
$router->addRoute('objectives', new Zend_Controller_Router_Route(
'task/:level/:objective/',
array(
'controller' => 'objectives',
'action' => 'tasks'
)
));
$router->addRoute('objectives', new Zend_Controller_Router_Route(
'task/:level/',
array(
'controller' => 'objectives',
'action' => 'tasks'
)
));
?>
However the last rule seems to overwrite the previous rules in the router.. I've read the Zend Documentation for the router over and over, I have a feeling im just missing something - should I be using a different router class?
Any help is Much Appreciated
As suspected I was overwriting the previous rules. The first argument for addRoute() is a name for the route, not the controller you are routing to as I thought. Giving each route a unique name fixed the problem.

Regex Routing - rule not being found

I'm defining regex routes for cleaning up my URLS. The idea is that all pages added by the user will be use the URL www.example.com/page-slug rather than using the actual controller, www.example.com/userpages/page-slug. Other pages will follow the standard module:controller:action routing scheme.
I'm trying to aceive this using router precedence.
I have defined the scheme below..
class Default_Bootstrap extends Zend_Application_Module_Bootstrap{
protected function _initRoute() {
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter(); // returns a rewrite router by default
$route['index'] = new Zend_Controller_Router_Route_Regex(
'/',
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
)
);
$route['contact'] = new Zend_Controller_Router_Route_Regex(
'contact/(\d+)',
array(
'module' => 'default',
'controller' => 'contact',
'action' => 'index'
)
);
$route['research'] = new Zend_Controller_Router_Route_Regex(
'research/(\d+)',
array(
'module' => 'default',
'controller' => 'research',
'action' => 'index'
)
);
$route['account'] = new Zend_Controller_Router_Route_Regex(
'account/(\d+)',
array(
'module' => 'default',
'controller' => 'account',
'action' => 'index'
)
);
$route['userpages'] = new Zend_Controller_Router_Route_Regex(
'/(.+)',
array(
'module' => 'default',
'controller' => 'userpages',
'action' => 'index'
),
array(
'slug' => 1
),
'%s'
);
$router->addRoute('userpages', $route['userpages']);
$router->addRoute('contact', $route['contact']);
$router->addRoute('research', $route['research']);
$router->addRoute('account', $route['account']);
$router->addRoute('index', $route['index']);
}
}
Things are generally working OK with the router precedence ensuring that index/account/research/contact pages are picking up the correct controller. However, when attempting to go to a URL covered by the "userpages" route e.g. "about-us", final catch all route is not being found resulting in...
Message: Invalid controller specified (about-us)
.
.
.
Request Parameters:
array (
'controller' => 'about-us',
'action' => 'index',
'module' => 'default',
)
Any idea where I'm going wrong here? It seems to me that the regex is correct "/(.+)" should be catching eveything that is not the index page.
EDIT: #phatfingers, OK you're right, I've edited "\d+" to ".+" to catch one or more of any character. The problem persists. In fact before changing the regex, I tried the URL www.example.com/52, and got the same error - "Invalid controller specified (52)". After the change - with code as per the edited snippet above, the rule is still failing to find any matches.
Drop the forward slash in the 'userpages' regex, i.e. just ('.+)
The quote is straight from the manual Zend Router and Router_Regex but afaik it also applies to all the routes.
Note: Leading and trailing slashes are trimmed from the URL in the
Router prior to a match. As a result, matching the URL
http://domain.com/foo/bar/, would involve a regex of foo/bar, and not
/foo/bar.

Pretty Zend Framework urls

I would like to have my urls like this:
/index
/contact
/articles
/articles/selection
...
Instead of:
/index/index
/index/contact
/articles/index
/articles/selection
...
Basically I have only one controller. Which solution is the best to perform this? (controllers and redirections, ZF routing, url rewriting, something else?)
Have a look at the documentation. The behaviour you want is configured as default in the default router:
http://framework.zend.com/manual/en/zend.controller.router.html
if the first param do not maps a module name, it will search for a controller and if this fails too, it is looking for an action in your IndexController.
Did you tried calling your url's like you want to?
What happens if you navigate to /index? Should be the same like /index/index
use zend routing :
$router = Zend_Controller_Front::getInstance()->getRouter();
$route_index = new Zend_Controller_Router_Route(':action', array(
'module' => 'default',
'controller' => 'index',
'action' => 'index'
));
$router->addRoute('route_index', $route_index );
$route_articles = new Zend_Controller_Router_Route('articles/:action', array(
'module' => 'default',
'controller' => 'articles',
'action' => 'index'
));
$router->addRoute('route_articles ', $route_articles );

Zend Framework routing

I'm trying to setup some routes for my ZF app but not getting too far. I have a controller 'WebServiceController', it has an index action and a lookupTransaction action. I want to use routes like this:
ws/
ws/lookupTransaction
Ideally I'd like anything with a 'ws/' prefix to go to the WebServiceController and match the action name. I'm not sure how to do that yet but I am trying to get each route working so I added these two routes:
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
function _initRoutes()
{
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->addRoute('ws', new Zend_Controller_Router_Route('ws/', array(
'controller' => 'web-service',
'action' => 'index',
)));
$router->addRoute('ws/lookupTransaction', new Zend_Controller_Router_Route('ws/lookupTransaction', array(
'controller' => 'web-service',
'action' => 'lookup-transaction',
)));
}
}
The first one works as expected but the second one doesn't, I just get 'Application Error'. What am I doing wrong? Just out of interest, if I remove my two routes and try and go to:
web-service/lookup-transaction
I still get the same error!
Solved
Here is how I can make it work with camel cased action name and camel cased URL.
$router->addRoute('ws', new Zend_Controller_Router_Route('ws/:action', array(
'controller' => 'web-service',
'action' => 'index',
)));
$router->addRoute('ws-lookupTransaction', new Zend_Controller_Router_Route('ws/lookupTransaction', array(
'controller' => 'web-service',
'action' => 'lookup-transaction',
)));
Thanks
Ziad
Try just this one route as a solution to both problems:
$router->addRoute('ws', new Zend_Controller_Router_Route('ws/:action', array(
'controller' => 'web-service',
'action' => 'index',
)));
the action parameter then serves as a default, so if no action is specified in the URL, index will be used. Otherwise it will route to the action in the URL. So example.com/ws/lookupTransaction will go to lookuptransactionAction() in your controller.
If this still gives you an error, post the error message so we can see what the problem is.
The router actually transforms URLs to lowercase. So the correct URL should be all lowercase dash separated words. Also I'm not sure if it's possible to use slash in route name (the first parameter of addRoute()).

Zend_Router parameter exceptions

My problem is I want some parameter values, passed through URL, don't trigger the Zend routing but lead to defaul controller/action pair.
Right now I have following in my index.php:
// *** routing info ***
$router = Zend_Controller_Front::getInstance()->getRouter();
$router->addRoute('showpage', new Zend_Controller_Router_Route('/show/:title',
array('controller' => 'Show',
'action' => 'page')));
// annoying exceptions :(
$router->addRoute('addshow', new Zend_Controller_Router_Route('/show/add',
array('controller' => 'Show',
'action' => 'add')));
$router->addRoute('saveshow', new Zend_Controller_Router_Route('/show/save',
array('controller' => 'Show',
'action' => 'save')));
$router->addRoute('addepisode', new Zend_Controller_Router_Route('/show/addEpisode',
array('controller' => 'Show',
'action' => 'addEpisode')));
$router->addRoute('saveepisode', new Zend_Controller_Router_Route('/show/saveEpisode',
array('controller' => 'Show',
'action' => 'saveEpisode')));
without last 4 routers, URL /show/add leads to show/page, carrying title == 'add'.
Please, every help will be much appreciated.
You can use a regular expression to reject add, save, addEpisode and saveEpisode
$router->addRoute(
'showpage',
new Zend_Controller_Router_Route(
'/show/:title',
array(
'controller' => 'show',
'action' => 'page'
),
array(
'title' => '(?:(?!add)(?!save)(?!addEpisode)(?!saveEpisode).)+'
)
)
)
First, use Zend_Controller_Router_Route_Static for the static routes.
Secondly, I'm pretty sure you don't need to include the leading forward slash, though I'm not sure if this is an issue.
As routes are matched in reverse order, yours should work (I think). For anything not matching "saveEpisode", "addEpisode", "save" or "add", it should fall through to the "showpage" route.
The only other thing I could think of would be to make the "showpage" route more specific, something like
'show/page/:title'