views:

204

answers:

3

For our CMS we have a site manager that defines the site's tree structure (sitemap if you want to call it that).

A possible url is www.example.com/our-team/developers/chris/ which would map in the tree structure to the node chris, child of developers which is in turn a child of out-team.

All this is in place and working thanks to the wonderfully implemented Nested Set behavior in doctrine. The only thing is that i'm struggling to get it working in the front end of our website. By default Zend framework's request object expects controller/action/key/value/key/value/... URI scheme but that isn't quite fitting my needs, i would like to skip the whole controller, action and key part and restrict to values. Something like value1/value2/value3/value4/...

Anyone has an idea how to accomplish this?

Edit: Some more background: You probably wonder how i'm mapping the request to a controller/action? Well every request that isn't dispatchable (thus isn't an existing controller/action) is handled by the error controller, it is there where i match the request URI against a path in the tree structure and thus am able to display the page (if the path matches), if it doesn't match the error controller just continues and a 404 is responded.

+2  A: 

That use case maps up to controller/action/value which is similiar to the standard pattern. Use something like :controller/:action/:username when defining your custom route.

See Using a Router in the manual for ZF.

chelmertz
That's something i know yes, it's actually this that i want to circumvent. Actually all i want is to be able to fetch each individual part from the URI in my PagesController ... something like $this->_request->getParamNr(5) which would fetch me the 5th part of the URI regardless of the actual key or value associated with that part of the uri
ChrisR
I guess that numbered approach would work until you reach a certain degree of rebuilding urls (*/our-team/developers/chris* becomes */our-team/chris*), wanting more readable code in controllers (`$this->getParam(5)` vs `$this->getParam('userId')`, or wants to associate the urls to models by allowing them to have the same name (`UserModel` could be used in `UserController`). There are probably more reasons.
chelmertz
If you still would like numbered urls, you should be able to use numbered indices of `$this->getRequest()->getParams()` in a controller, but you would still have to use some rewriting (and catching everything in the ErrorController is a good way to lose maintainability, in the sense that it doesn't make sense.)
chelmertz
+1  A: 

Firstly, I'd stop using the error controller to provide routing. Thats just plain bad juju.

Now there are a few things to consider when dealing with a routeing structure like this, one is that this conflicts with the default route, so if your relying on it, your going to need to be strict about how you do so.

given the information you have made available here, I would suggest you subclass the route class, and perform a (cached) lookup against your database, and return the correct module/controller/action from there, and go straight to the correct action in the first place.

You can also then pass the relevant data along in the request params (page content, team member details etc) so that a further db lookup is not required in your action, and your action code if free of lookup cruft.

Bittarman
+2  A: 

I accomplished the routing by extending the Zend_Controller_Router_Route_Abstract class.

By adding it to the router stack, it is possible to use a 'waterfall' system using many routes.

I published the code on my blog and it works as Bittarman suggested.

coudenysj