カスタム投稿タイプとパーマリンクと分割ページ

WordPressで、カスタム投稿タイプを作って、テーマを作り込んでいる途中、ちょっとはまった点があり、その備忘録です。

まぁ、既存のプラグインを導入すればいいわけですが、一つのテーマ内で全てを完結させたい、という方針で作ってる訳です、ハイ。
導入も簡単ですしね。プラグインをアレとコレと入れて、設定して・・・という手間はなるべく避けたいわけです。

さて、本題。

カスタム投稿タイプを作ってパーマリンクを投稿IDでアクセスさせようとしました。要するに・・・

ttp://hoge.com/information/123

っていう風に。これ自体はFAQなので、検索すると、下記コードが載ったブログ記事がいっぱいヒットします。

/* カスタム投稿タイプ information の例 */

add_action('init', 'myposttype_rewrite');
function myposttype_rewrite() {
    global $wp_rewrite;
    $queryarg = 'post_type=information&p=';
    $wp_rewrite->add_rewrite_tag('%information_id%', '([^/]+)', $queryarg);
    $wp_rewrite->add_permastruct('information', '/information/%information_id%', false);
}

add_filter('post_type_link', 'myposttype_permalink', 1, 3);
function myposttype_permalink($post_link, $id = 0, $leavename) {
    global $wp_rewrite;
    $post = &get_post($id);
    if ( is_wp_error( $post ) )
        return $post;
    $newlink = $wp_rewrite->get_extra_permastruct('information');
    $newlink = str_replace("%information_id%", $post->ID, $newlink);
    $newlink = home_url(user_trailingslashit($newlink));
    return $newlink;
}

だけど・・・これ現在のバージョン(3.5)では致命的な欠陥があります。

カスタム投稿タイプの投稿記事内に分割ページ(<!–nextpage–>>)を入れて、2ページ目、3ページ目・・・とアクセスできません。
要するに・・・

ttp://hoge.com/information/123/2

などのようにアクセスすると、投稿がありません、とかなってしまいます。つまり、上記コードを入れることで、Rewrite処理が上手く機能しなくなっているようです。試しに上記コードをコメントアウトすると、ちゃんと分割ページが機能します。カスタム投稿タイプのパーマリンクは、%postname%になっているはずですから、以下のようになるわけです。

ttp://hoge.com/information/投稿のタイトルのスラッグ/2

おそらく、パーマリンクを投稿IDにする、上記コードには何かが足りないのだと思います。Wordpressのフォーラムにも質問を投げて見たのですが結局アドバイス頂けなかったので、いろいろ試行錯誤しながら調べた結果、以下の一行を入れることで、無事分割ページが機能するようになりました。

/* ごめんなさい、浅学なんで、これで上手くいく理屈が分かりません。 */
$post_type = 'information'; //これはサンプル
add_rewrite_rule(&quot;{$post_type}/(.+?)/([0-9]+)$&quot;,'index.php?post_type='.$post_type.'&amp;p=$matches[1]&amp;page=$matches[2]','top');

つまり、分割ページのために、リライトルールを一個追加してしまえ、ってことです。

それと、ネットで検索して出てくる上記コードで、現在のWordpressのバージョンにおいて、フィルターフック名 ‘post_type_link’ でのコールバック関数の第二引数が間違っていると思います。

//上記コードでは、
function myposttype_permalink($post_link, $id = 0, $leavename){}

//となってますが、今のバージョンでは、
function myposttype_permalink($post_link,$post,$leavename){}

//という風に、バージョン3.1から、投稿IDではなく、WP_Postオブジェクト自体が渡されるように変更になっていると思われます。
// 参考URL http://adambrown.info/p/wp_hooks/hook/post_type_link

この点も踏まえて、修正したコードが、以下のようになります。

/* カスタム投稿タイプ information の例 の分割ページ対応修正版 */
add_action('init', 'myposttype_rewrite');
function myposttype_rewrite() {
    global $wp_rewrite;
    $queryarg = 'post_type=information&amp;p=';
    $wp_rewrite-&gt;add_rewrite_tag('%information_id%', '([^/]+)', $queryarg);
    $wp_rewrite-&gt;add_permastruct('information', '/information/%information_id%', false);

    add_rewrite_rule(&quot;information/(.+?)/([0-9]+)$&quot;,'index.php?post_type=information&amp;p=$matches[1]&amp;page=$matches[2]','top');
}

add_filter('post_type_link', 'myposttype_permalink', 1, 3);
function myposttype_permalink($post_link, $post, $leavename) {
    global $wp_rewrite;

    $newlink = $wp_rewrite-&gt;get_extra_permastruct('information');
    $newlink = str_replace(&quot;%information_id%&quot;, $post-&gt;ID, $newlink);
    $newlink = home_url(user_trailingslashit($newlink));
    return $newlink;
}

でも、この修正によって、別の不具合が出るかも・・・。まぁ、いいや。

パーマリンク関係のコードを変更したら、必ず、設定 => パーマリンクの空更新を忘れずに。