【问题标题】:SEO routes for nested categories with paginator and articles带有分页器和文章的嵌套类别的 SEO 路由
【发布时间】:2012-11-10 07:02:37
【问题描述】:

具有嵌套类别的人类可读 URL,例如 /category/subcategory/n-subcategories/article。我正在使用 CakePHP 2.2.3 并且找不到路由问题的合适解决方案。使用 2 个表:

  • 文章(也可以是产品或帖子或...)
    • 只有一个普通的“单一”视图
    • 一篇文章属于一个类别
  • 类别
    • 嵌套(具有 n 级的树行为)
    • 一个类别可以有很多篇文章
    • category-view 列出与该类别相关的所有文章
    • 分类视图使用分页器显示文章列表

我猜是一个非常常见的例子。但是我现在如何定义路由器,以获取具有嵌套类别的 URL 路径,如下所示:

/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)

我尝试在 routes.php 中修复所有路由,但这不是很舒服,我认为应该有一个动态解决方案。

我还尝试自动生成类别和文章别名之外的所有路由并将它们保存在单独的“路由”数据库表中 - 它有效,但我认为没有必要定义单个路由的 hunderets? !

我也尝试在路由器中定义所有类别修复,例如

Router::connect(
  '/any-category-name',
  array('controller' => 'categories', 'action' => 'view', 1)
);

然后是文章

Router::connect(
  '/any-category-name/:slug',
  array('controller' => 'articles', 'action' => 'view'),
  array('pass' => array('slug'))
);

但是使用这种方法,所有文章都可以在所有类别中找到,这不是一个好的解决方案。我考虑过使用

Router::connect(
  '/:slug', ...

但我不知道该怎么做,因为可能有两个不同的控制器和两个不同的视图(我也不知道分页在这种情况下是否仍然有效以及会发生什么,如果我也想在安装中使用更多控制器/操作)。

我认为在 Cake 中使用两个控制器(类别和文章)获取嵌套 url 应该不难?!感谢您提供任何有用的建议!

【问题讨论】:

    标签: cakephp tree routes slug cakephp-2.2


    【解决方案1】:

    我认为你必须检查两件事:

    1) 检查 url 中的类别数量和
    2) 检查最后一个参数是分类还是文章

    在(动态)路由中处理这两项检查可能非常困难。我建议为所有这些请求创建一个路由,并在控制器中检查 1) 和 2)。

    路线可能是这样的:

    Router::connect(
      '/*',
      array('controller' => 'outputs', 'action' => 'index')
    );
    

    我为此路由调用了控制器 OutputController,因为这将是处理所有这些 url 的输出的控制器。

    class OutputController extends AppController
    {
      public $uses = array('Article', 'Category');
    
      public function index()
      {
        // Get n parameters from url (1)
        $args = func_get_args();
        $last_arg = $args[count($args) - 1];
    
        // Check if this is an article (2)
        $article = $this->Article->find('first', array(
          'conditions' => array('Article.slug' => $last_arg
        ));
        if (!empty($article)) {
          $this->set('article', $article);
          $this->render('article');
        }
    
        // Check if this is an category (2)
        $category = $this->Category->find('first', array(
          'conditions' => array('Category.slug' => $last_arg
        ));
        if (!empty($category)) {
          $this->set('category', $category);
          $this->render('category');
        }
    
        // Page not found
        if (empty($article) and empty($category)) {
          throw new NotFoundException();
        }
      }
    
      // ...
    

    为了显示一篇文章,使用了“Output/article.ctp”视图。对于一个类别,CakePHP 呈现“Output/category.ctp”。此外,您可以使用 $args 中的参数为您的(子)类别获取所有必要的数据。

    【讨论】:

    • 非常感谢,我将不得不尝试这种方式,但它看起来是一个不错的解决方案。我认为 Category-Slug 和 Article-Slug 需要是唯一的才能工作,但如果我将 Routes 存储在数据库表中,这也是必要的......谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 2014-10-03
    • 1970-01-01
    • 2017-05-19
    • 2021-08-08
    相关资源
    最近更新 更多