代码之家  ›  专栏  ›  技术社区  ›  Stephen

CakePHP与beforeFilter的奇怪行为:我无法将变量设置为视图

  •  0
  • Stephen  · 技术社区  · 14 年前

    设置需要一些设置:

    我正在研究一种方法,在我的cakePHP驱动的博客的URL中使用漂亮的post title“slugs”。

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

    显然,我不会为每一篇文章都编写一个新的方法,所以我尽量做到圆滑,并使用CakePHP回调来模拟php5的行为 __call() 可以在控制器中调用。

    到目前为止我所做的:

    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 方法。 单逯柱 从模型中获取数据,并设置一个变量 $post 为了看风景。

    还有一个 index 方法显示最近10篇文章。

    以下是令人困惑的部分:

    $this->render 方法。

    1. 呼叫 $this->render('single_post') ,视图渲染一次,但是 未设置变量。
    2. 当我 $邮政 变量集,然后用它再次呈现 . 实际上,我在同一个文档中得到了两个完整的布局,一个接一个。一个有内容,一个没有。

    单逯柱 以及一个名为 __single_post 两者都有同样的问题。我希望最终结果是一个名为 __单逯柱 所以不能用url直接访问它 /blog/single_post .

    阿尔索

    我还没有编写错误处理代码,当帖子不存在时(这样当人们在url中输入随机的东西时,他们不会得到单一的“帖子”视图)。我计划在解决这个问题后再做。

    1 回复  |  直到 14 年前
        1
  •  1
  •   deceze    14 年前

    这并不能明确回答您的问题,但我只需通过使用路径来解决问题,从而抛开整个复杂性:

    // 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' */));
    

    请注意,在撰写本文时,上述路径仅依赖于最近的一个bug修复,并将其合并到Cake中(参见 http://cakephp.lighthouseapp.com/projects/42648/tickets/1197-routing-error-when-using-regex-on-action ). 有关更兼容的解决方案,请参阅此帖子的编辑历史记录。

    至于 single_post 方法可以直接访问:我不会 /blog/:slug 路线捕捉器 全部的 以开头的URL /blog/ ,它会抓住的 /blog/single_post 然后调用 BlogPostsController::single_post('single_post') . 然后,您将尝试找到一个带有“single_post”的帖子,这个帖子可能不存在。在这种情况下,您可以抛出404错误:

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

    错误处理:完成。