具有分页和文章的嵌套类别的SEO路线

时间:2012-11-21 22:41:35

标签: cakephp tree routes slug cakephp-2.2

具有嵌套类别的人类可读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中修复所有路由,但这不太舒服,我认为应该有一个动态解决方案。

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

我还尝试过定义路由器中的所有类别修复,例如

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', ...

但我不知道如何继续,因为有两个不同的控制器和两个不同的视图可能(我也不知道在这种情况下Pagination是否仍然可以工作,如果我也想要发生什么在安装中使用更多控制器/操作。)

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

1 个答案:

答案 0 :(得分:0)

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

1)检查网址和
中的类别数量 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中的参数来获取(子)类别的所有必要数据。