我在CakePHP应用程序中设置了一个支持嵌套类别的类别结构。也就是说,一个类别可以有一个子类别和/或一个父类别。categories
表的数据库列为:id
、parent_id
、lft
、rght
、name
、slug
。
我已经为类别和与这些类别相关的帖子编写了所有CRUD逻辑。
例如,假设我有一个名为about
的类别和一个子类别me
。我希望像mysite.com/about/me
这样的URL显示所有与me
类别相关的帖子。
我很难确定如何发送此请求。如果我只做Router::connect('/:category', array('controller' => 'categories', 'action' => 'view'))
,它只适用于mysite.com/about
,而我不能只做/:category/:category/:category
,因为它根本不可伸缩。
如何实现嵌套类别的路由?
您可以对路线使用*
运算符。
如果您知道路线将只有一个子类别,则您的路线应为
Router::connect('/:category/*',
array('controller' => 'categories', 'action' => 'view'))
这将匹配mysite.com/about/me
,并将其传递给类似的操作
CategoriesController->view('me')
me
将作为参数传递,您可以在该操作中执行所有查询等操作。
然而,如果类别的嵌套具有无法定义的长度,那么方法就不同了。假设您还想映射一个类似mysite.com/about/me/2012/march
的url。那么路由规则可以是
Router::connect('/:category/**',
array('controller' => 'categories', 'action' => 'view'))
双**
在文档中被称为
使用尾随的双星,将捕获URL的剩余部分作为单个传递的参数。当你想使用一个包含的参数时,这很有用
因此,类别之后的所有内容都将作为参数传递。在本例中,它将调用
CategoriesController->view('me/2012/march')
在这个操作中,您必须对参数进行解析,以获得所需的嵌套。我建议在控制器中将该功能提取为受保护或私有功能
class Categories as AppController {
public function view($url_params) {
//it could be a string or an array or etc, depends on how you want to handle it
$array = $this->_parseCategories($url_params);
}
protected function _parseCategories($stringUrl) {
$subcategories = explode('/', $stringUrl);
//add whatever else you want to do
return $subcategories;
}
}
您应该根据需要调整路线(我没有包括:category
的通过),也可以稍微更改控制器,但它应该具有足够的可扩展性