【问题标题】:Routing for nested categories嵌套类别的路由
【发布时间】:2013-07-02 20:19:05
【问题描述】:

我在我的 CakePHP 应用程序中设置了一个支持嵌套类别的类别结构。也就是说,一个类别可以有一个孩子和/或一个父母。 categories 表的数据库列是:idparent_idlftrghtnameslug

我已经为类别和与这些类别相关的帖子编写了所有 CRUD 逻辑。

例如,假设我有一个名为 about 的类别和一个名为 me 的子类别。我希望像 mysite.com/about/me 这样的 URL 显示与 me 类别相关的所有帖子。

我无法确定如何路由此请求。如果我只做Router::connect('/:category', array('controller' => 'categories', 'action' => 'view')),它只适用于mysite.com/about,我不能只做/:category/:category/:category,因为它根本无法扩展。

如何实现嵌套类别的路由?

【问题讨论】:

    标签: php cakephp routing


    【解决方案1】:

    您可以使用*operator for routes

    如果您知道路线只有一个子类别,那么您的路线应该是

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

    这将匹配 mysite.com/about/me 并将其传递给这样的操作

    CategoriesController->view('me')
    

    me 将作为参数传递,您可以在该操作中执行所有查询等。

    但是,如果类别的嵌套具有您无法定义的长度,则方法会有所不同。假设您还想映射像mysite.com/about/me/2012/march 这样的网址。那么路由规则可以是

    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的传递),并且稍微改变一下控制器,但它应该具有足够的可扩展性

    【讨论】:

    • ** 正是我所需要的,谢谢!但是我刚刚发现了另一个问题,我的帖子路由定义为/:category/:slug,那么该路由和/:category/** 在某些情况下不会“碰撞”吗?
    • 是的,在某些情况下它会发生碰撞。你应该把/:category/:slug 之前 /:category/**。对于像about/me 这样的网址,cake 将使用/:category/:slug,对于about/me/please,它应该使用**。例如,一个解决方案可能是使用/post/:category/:slug 更改slug 路由,因此每个帖子都会有一个类似post/about/me 的网址。或者只留下** 并让CategoryController->view($params) 处理如果它只是一个帖子或子类别帖子的列表。 (我喜欢第二个选项,更漂亮的网址...但第一个选项对控制器的压力较小...)
    猜你喜欢
    • 1970-01-01
    • 2019-10-18
    • 2020-07-06
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2019-12-20
    相关资源
    最近更新 更多