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 中修复所有路由,但这不是很舒服,我认为应该有一个动态解决方案。

我还尝试自动生成类别和文章别名之外的所有路由并将它们保存在单独的“路由”数据库表中 - 它有效,但我认为没有必要定义单个路由的 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 应该不难?!感谢您提供任何有用的建议!

4

1 回答 1

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 中的参数为您的(子)类别获取所有必要的数据。

于 2012-11-25T10:42:18.737 回答