简体   繁体   English

嵌套类别的路由

[英]Routing for nested categories

I have a category structure set up in my CakePHP application which supports nested categories. 我在CakePHP应用程序中设置了类别结构,该结构支持嵌套类别。 That is, a category can have a child and/or a parent. 也就是说,一个类别可以有一个孩子和/或一个父母。 The database columns for the categories table are: id , parent_id , lft , rght , name , slug . categories表的数据库lftidparent_idlftrghtnameslug

I've already written all the CRUD logic for categories and posts relating to those categories. 我已经为类别和与这些类别相关的帖子编写了所有CRUD逻辑。

As an example, say I have a category called about and a sub-category called me . 例如,假设我有一个名为about的类别和一个名为me的子类别。 I would like URLs like mysite.com/about/me to show all the posts related to the me category. 我希望像mysite.com/about/me这样的URL显示与me类别相关的所有帖子。

I'm having trouble working out how to route this request. 我在解决如何路由此请求时遇到了麻烦。 If I just do Router::connect('/:category', array('controller' => 'categories', 'action' => 'view')) it will only work for mysite.com/about , and I can't just do /:category/:category/:category because it isnt at all scale-able. 如果我只做Router::connect('/:category', array('controller' => 'categories', 'action' => 'view'))它仅适用于mysite.com/about ,我可以不仅要做/:category/:category/:category因为它并不是所有可扩展的。

How can I achieve routing for nested categories? 如何实现嵌套类别的路由?

You can use the * operator for routes . 您可以将* 运算符用于路由

If you know the routes will only have one sub-category, your route should be 如果您知道路线只有一个子类别,则您的路线应为

Router::connect('/:category/*', 
                 array('controller' => 'categories', 'action' => 'view'))

That will match mysite.com/about/me and pass it to the action like this 那将匹配mysite.com/about/me并将其传递给这样的动作

CategoriesController->view('me')

me will be passed as parameter and you can do all the queries and etc inside that action. me将作为参数传递,您可以在该操作内执行所有查询等操作。

If, however, the nesting of categories have a length you can't define, the approach is different. 但是,如果类别嵌套的长度无法定义,则方法会有所不同。 Let's say you also want to map an url like mysite.com/about/me/2012/march . 假设您还想映射一个网址,例如mysite.com/about/me/2012/march Then the route rule can be 那么路由规则可以是

Router::connect('/:category/**', 
                 array('controller' => 'categories', 'action' => 'view'))

That double ** is referred in the docs as 该双**在文档中称为

Using a trailing double star, will capture the remainder of a URL as a single passed argument. 使用结尾双星,将捕获URL的其余部分作为单个传递的参数。 This is useful when you want to use an argument that included a / in it 当您要使用包含/的参数时,这很有用

So, everything after the category will be passed as parameter. 因此,类别之后的所有内容都将作为参数传递。 In this example it will call 在此示例中,它将调用

CategoriesController->view('me/2012/march')

and in that action you'll have to do a parse of the parameter to get the nesting you want. 在该操作中,您将必须解析参数以获得所需的嵌套。 I recommend extracting that function as a protected or private function in the controller 我建议在控制器中将该功能提取为受保护或私有功能

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;
    }
}

You should adjust the routes as you need (I didn't include the passing of :category ), and also change the controller a bit, but it should be scalable enough 您应该根据需要调整路由(我没有包括:category的传递),并且还稍微更改了控制器,但是它应该具有足够的可伸缩性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM