Human readable URLs with nested categories like /category/subcategory/n-subcategories/article. I’m using CakePHP 2.2.3 and can’t find a proper solution for a routing problem. Using 2 Tables:
- articles (could also be products or posts or…)
- have just a normal “single” view
- an article belongs to one category
- categories
- nested (Tree behaviour with n-levels)
- one category can have many articles
- category-view lists all articles, that are related to this category
- category view uses paginator for showing article lists
A very common example I guess. But how do I have to define the router now, to get URL-paths with the nested categories like this:
/categoryname1 (showing category view)
/categoryname1/articlename1 (showing article view)
/categoryname2/articlename2 (showing article view)
/categoryname2/subcategoryname1 (showing category view)
/categoryname2/subcategoryname2/articlename4 (showing article view)
/n-categoryname/././...n-subcategoryname (showing category view)
/n-categoryname/././...n-subcategoryname/n-articlename (article view)
I tried to make all routes fix in the routes.php, but that is not very comfortable and I think there should be a dynamic solution.
I also tried to automatically generate all routes out of category- and article-alias and save them in a separate “routes” database table – it worked, but I don’t think it’s really necessary to define hunderets of single routes?!
I also tried just to define all the categories fix in router, like
Router::connect(
'/any-category-name',
array('controller' => 'categories', 'action' => 'view', 1)
);
and then for the articles
Router::connect(
'/any-category-name/:slug',
array('controller' => 'articles', 'action' => 'view'),
array('pass' => array('slug'))
);
But with this method, all articles are available in all categories, which isn’t a good solution. And I thought about using
Router::connect(
'/:slug', ...
but I don’t know how to go on, because there are two different controllers and two different views possible (also I don’t know if Pagination will still work in this case and what will happen, if I also want to use more controllers/actions in the installation).
I think it shouldn’t be so difficult to get nested urls with two controllers (categories and articles) in Cake?! Thanks for any helpful advise!
I think you have to check for two things:
1) Check the number of categories in the url and
2) Check if the last parameter is a category or an article
Handle both checks within a (dynamic) route may be very difficult. I would suggest to create just one route for all these requests and do the checks for 1) and 2) in a controller.
The route may be something like this:
I called the controller for this route OutputController because this will be the controller that handles the output for all these urls.
To display an article, the view ‘Output/article.ctp’ is used. For a category, CakePHP renders ‘Output/category.ctp’. In addition you can use the parameters in $args to fetch all the necessary data for your (sub-) categories.