0

さて、これにはいくつかのセットアップが必要です:

CakePHP を使用したブログの URL で、素敵な投稿タイトル「スラッグ」を使用する方法を検討しています。

例:/blog/post-title-hereの代わりに/blog/view_post/123.

投稿ごとに新しいメソッドを書くつもりはないのは明らかなので、CakePHP コールバックを使用して PHP 5 の__call()マジック メソッドの動作をエミュレートしようとしています。ご存じない方のために説明すると、CakePHP のディスパッチャーはメソッドが存在するかどうかを確認__call()し、コントローラーで呼び出す前に CakePHP エラーをスローします。

私がこれまでに行ったこと:

完全な開示のために(問題が発生した理由がわからないため)、2つのルートがあります。

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_postsingle_postモデルからデータを取得し$post、ビューの変数を設定します。

index最新の 10件の投稿を表示する方法もあります。

交絡部分は次のとおりです。

$this->render上記でコメントアウトされたメソッドがあることに気付くでしょう。

  1. を呼び出さない$this->render('single_post')と、ビューは 1 回レンダリングされますが、$post変数は設定されません。
  2. を呼び出すと、ビューは変数が設定された状態でレンダリングされ、設定されていない状態で再度レンダリングされます。つまり、同じドキュメント内で 2 つの完全なレイアウトを次々に取得します。内容のあるものとないもの。$this->render('single_post')$post

single_postという名前のメソッドとという名前のメソッドを使用してみました__single_postが、どちらも同じ問題を抱えています。__single_posturl で直接アクセスできないように、最終結果をメソッドという名前にすることをお勧めし/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-を参照)。 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
}

エラー処理: 完了。

于 2010-10-03T02:04:14.123 に答える