0

好的,这将需要一些设置:

我正在研究一种在我的 cakePHP 驱动博客的 URL 中使用漂亮的帖子标题“slugs”的方法。

例如:/blog/post-title-here而不是/blog/view_post/123.

由于我显然不会为每篇文章都编写一个新方法,因此我试图巧妙地使用 CakePHP 回调来模拟 PHP 5__call()魔术方法的行为。对于那些不知道的人,CakePHP 的调度程序会检查一个方法是否存在,并__call()在控制器调用之前抛出一个 cakePHP 错误。

到目前为止我所做的:

为了充分披露(因为我不知道为什么会遇到问题),我有两条路线:

Router::connect('/blog/:action/*', array('controller' => 'blog_posts'));
Router::connect('/blog/*', array('controller' => 'blog_posts'));

这些为 BlogPostsController 设置了一个别名,这样我的 url 看起来就不像/blog_posts/action

然后在 BlogPostsController 中:

public function beforeFilter() {
    parent::beforeFilter();
    if (!in_array($this->params['action'], $this->methods)) {
        $this->setAction('single_post', $this->params['action']);
    }
}
public function single_post($slug = NULL) {
    $post = $this->BlogPost->get_post_by_slug($slug);
    $this->set('post', $post);
    //$this->render('single_post');
}

beforeFilter捕获不存在的动作并将它们传递给我的single_post方法。 single_post从模型中获取数据,并$post为视图设置一个变量。

还有一种index方法可以显示最近的 10 个帖子。

这是令人困惑的部分:

你会注意到$this->render上面有一个方法被注释掉了。

  1. 当我调用$this->render('single_post')时,视图呈现一次,但未设置$post变量。
  2. 当我调用$this->render('single_post'),视图会使用$post变量 set 进行渲染,然后再次使用未设置的变量进行渲染。所以实际上我在同一个文档中得到了两个完整的布局,一个接一个。一个有内容,一个没有。

我试过使用一个名为的方法single_post和一个名为的方法__single_post,它们都有同样的问题。我希望最终结果是一个名为的方法__single_post,这样就不能直接使用 url 访问它/blog/single_post

当帖子不存在时,我还没有编写错误处理代码(因此当人们在 url 中键入随机内容时,他们不会得到 single_post 视图)。在我弄清楚这个问题后,我打算这样做。

4

1 回答 1

1

这并没有明确回答您的问题,但我只是通过仅使用路线解决问题来放弃整个复杂性:

// Whitelist other public actions in BlogPostsController first,
// so they're not caught by the catch-all slug rule.
// This whitelists BlogPostsController::other() and ::actions(), so
// the URLs /blog/other/foo and /blog/actions/bar still work.
Router::connect('/blog/:action/*',
                array('controller' => 'blog_posts'),
                array('action' => 'other|actions'));

// Connect all URLs not matching the above, like /blog/my-frist-post,
// to BlogPostsController::single_post($slug). Optionally use RegEx to
// filter slug format.
Router::connect('/blog/:slug',
                array('controller' => 'blog_posts', 'action' => 'single_post'),
                array('pass' => array('slug') /*, 'slug' => 'regex for slug' */));

请注意,上述路线仅依赖于最近的错误修复,截至撰写本文时,已合并到 Cake 中(请参阅http://cakephp.lighthouseapp.com/projects/42648/tickets/1197-routing-error-when-使用正则表达式操作)。查看这篇文章的编辑历史以获得更兼容的解决方案。

至于single_post直接访问的方法:我不会。由于该/blog/:slug路由捕获所有以 开头的 URL /blog/,因此它将捕获/blog/single_post并调用BlogPostsController::single_post('single_post')。然后,您将尝试查找带有 slug“single_post”的帖子,该帖子可能不存在。在这种情况下,您可以抛出 404 错误:

function single_post($slug) {
    $post = $this->BlogPost->get_post_by_slug($slug);
    if (!$post) {
        $this->cakeError('error404');
    }

    // business as usual here
}

错误处理:完成。

于 2010-10-03T02:04:14.123 回答