Reputation: 41
I'm trying to create a route that will "cover" this kind of URLs:
www.test.com/parent1/parent2/parent3/item
www.test.com/parent1/parent2/parent3/parent4/item1
Number of those parents in unspecified, and it should only serve to give a better, more intuitive look to site URLs. Main parameter is that "item".
I suppose that only way to solve that is to use Route_Regex, and so I tried to accomplish this route task with something like this:
routes.test.type = "Zend_Controller_Router_Route_Regex"
routes.test.route = "test/(?:.*)?([^\/]+)"
routes.test.defaults.module = default
routes.test.defaults.controller = test
routes.test.defaults.action = index
routes.test.map.1 = "path"
routes.test.map.2 = "item"
routes.test.reverse = "test/%s%s"
I haven't been testing this to much, because I'm not sure if I'm doing the right thing... I have no idea how that regex should even look like, and how should I treat that "path".
Can you advice what should I do to fulfill this kind of route demand? So, I need that path (parent1, parent2, etc.) only for appearance, and main param is that "item"...
Upvotes: 4
Views: 5520
Reputation: 112230
If the parent items are completely unimportant, a simple solution might be to remove them before they even reach Zend - that is, rewrite the URLs so it only every sees test/:item
For example, using:
RewriteEngine On
RewriteRule ^(test/).*/([^/]+) $1$2 [L]
(The "test/" part can obviously be changed or made dynamic as required.)
That goes into Apache's config file for the site - or in .htaccess file on shared hosting.
If you're not using Apache, check the URL rewriting functionality for whatever web server you're using - the syntax may vary slightly but will be similar.
Upvotes: 1
Reputation: 91
I know this is an old question, but I had a similar problem and just thought I should post my solution. Maybe it can help others viewing this question.
I wrote my routes in a plugin, Obviously you need to add the plugin into the bootstrap for this to work ;)
class Plugin_RoutesPage extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
$front_controller = Zend_Controller_Front::getInstance();
$router = $front_controller->getRouter();
// Page SEO friendly hierarchical urls
$routePageSeoTree = new Zend_Controller_Router_Route_Regex(
'([-a-zA-Z0-9/]+)/([-a-zA-Z0-9]+)',
array(
// default Route Values
'controller' => 'page',
'action' => 'open',
),
array(
// regex matched set names
1 => 'parents',
2 => 'item'
)
);
$router->addRoute('page-seo-tree',$routePageSeoTree);
// only one level
$routeSinglePage = new Zend_Controller_Router_Route_Regex(
'([-a-zA-Z0-9]+)',
array(
// default Route Values
'controller' => 'page',
'action' => 'open',
),
array(
// regex matched set names
1 => 'item'
)
);
$router->addRoute('page-single',$routeSinglePage);
}
}
This is how you can use it in your controller's action
class PageController extends Zend_Controller_Action
{
public function openAction()
{
// the part of the uri that you are interested in
$item = $this->_request->getParam('item');
}
}
Here's a quick example of how to include it into your bootstrap
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initPlugins()
{
$front_controller = Zend_Controller_Front::getInstance();
$front_controller->registerPlugin(new Plugin_RoutesPage(), 1);
}
}
I had to use two routes, because the current page we are trying to view/open might not have any parents. I'm sure there's probably a better way to write the regex, but this is what worked for me. If anyone knows how to improve the regex, please let me know.
Upvotes: 6
Reputation: 112230
I don't know what zend route is (something php related?), but if you can use normal programming functions then a much simpler solution than a regex is to use built-in list/split functions, eg:
end(explode($Url,'/'))
Url.split('/').last()
ListLast(Url,'/')
etc
If you do need a regex, you can do it simply with this:
[^/]+$
That will give you everything after the last forward-slash upto the end of the line.
(You only need to escape the /
with a backslash if you're using it in a context which requires escaping.)
(btw, in your example, you've got test/
at the start - is that deliberate/required?)
Upvotes: -2