WordPress

【Wordpress】カスタム投稿タイプのパーマリンクをスラッグから記事IDに変更してみた

2018/02/10
記事に掲載しているソースのうち、custom_posttype_rewrite()custom_posttype_permalink()のソースを一部修正しました。
それに伴って、一部の解説文の文章も修正しています。

先日、カスタム投稿タイプのパーマリンクを変更する任務を受け意気揚々と挑んだのですが、なかなか苦戦したので備忘録も兼ねてパーマリンクの変更方法をまとめました。
「カスタム投稿タイプのパーマリンクを変更したい…でも色々な事情からプラグインが使えない」とお嘆きの方などのお役に立てればと幸いです。ちなみにプラグインの使用に制限がない方は、プラグインを使ったほうが簡単かつ確実かと思います。

パーマリンクを編集するプラグインの一例
Custom Post Type Permalinks

また、この記事で記載した方法以外にいい実装方法をご存知の方はお教えいただければと思います。

1.今回実装する機能について

例えば有名な「Custom post type UI」で実装したカスタム投稿タイプのパーマリンクはttps://example.com/カスタム投稿タイプ/スラッグという形で出力されますが、今回はこれをttps://example.com/カスタム投稿タイプ/記事IDという形に変更します。

使用するバージョンは以下の通りです。

今回使用するバージョン
WordPress 4.9.1

2.ソース

手順を解説する前に今回実装するコードの全体像を見ていきましょう。
以下のコードをfunctions.phpに記載していきます。
「books」の部分は自分の実装したいカスタム投稿タイプのスラッグに変更しましょう。

functions.php
add_action('init', 'custom_posttype_rewrite');

function custom_posttype_rewrite() {

    global $wp_rewrite;

    $wp_rewrite->add_rewrite_tag('%books%', '(books)','post_type=');

    $wp_rewrite->add_permastruct('books', '/%books%/%post_id%/', false);

}

add_filter('post_type_link', 'custom_posttype_permalink', 1, 3);

function custom_posttype_permalink($post_link, $id = 0, $leavename) {

    global $wp_rewrite;

    $post = &get_post($id);

    if(is_wp_error( $post )){
        return $post;
    }

    if('books' === $post->post_type){
        $newlink = $wp_rewrite->get_extra_permastruct($post->post_type);

        $newlink = str_replace('%books%', $post->post_type, $newlink);

        $newlink = str_replace('%post_id%', $post->ID, $newlink);

        $newlink = home_url(user_trailingslashit($newlink));

        return $newlink;
    }

    return $post_link;
}

3.実装手順

上記のソースで、3つの処理を実装しています。
1. 「投稿タイプ」を取得するリライトタグの設定
2. カスタム投稿タイプのパーマリンク構造の設定
3. 「post_type_link」フックでパーマリンクURLを編集
4. リライトルールを更新する

1.「投稿タイプ」を取得するリライトタグの設定

デフォルトでは、投稿タイプを取得するリライトタグが存在しないので、これを設定します。add_rewrite_tag()を使って設定しましょう。
第一引数はリライトタグ名、第二引数にはリクエストされたURLに対してタグの値が存在するかを検証するための正規表現、第三引数に正規表現でフェッチした値をどのクエリに当てはめるかを設定します。

この例では%post_type%というリライトタグを設定しています。
この例では%books%というリライトタグを設定しています。
正規表現でフェッチした値は「post_type」のクエリに渡されます。

functions.php
$wp_rewrite->add_rewrite_tag('%books%', '([a-zA-Z0-9]+)','post_type=');

2.カスタム投稿タイプのパーマリンク構造の設定

次にカスタム投稿タイプ「books」用のパーマリンク構造を設定します。
今回はttps://example.com/カスタム投稿タイプ/記事IDというパーマリンクを実現したいので、先ほど登録した%post_type%と既存のリライトタグ%post_id%を使用して以下のように設定しました。
今回はttps://example.com/カスタム投稿タイプ/記事IDというパーマリンクを実現したいので、先ほど登録した%books%と既存のリライトタグ%post_id%を使用して以下のように設定しました。

これでカスタム投稿タイプ「books」の記事にアクセスした際、
ttps://example.com/%books%/%post_id%
という形のURLが返ってくるようになります。

functions.php
$wp_rewrite->add_permastruct('books', '/%books%/%post_id%/', false);

3.「post_type_link」フックでパーマリンクURLを編集

2までの段階ではどの「books」タイプの投稿にアクセスしてもttps://example.com/%post_type%/%post_id%のURLが返ってきてしまい、対象の記事にアクセスできません。そこで各記事に対応した形のURLにするために置換作業を行います。
2までの段階ではどの「books」タイプの投稿にアクセスしてもttps://example.com/%books%/%post_id%のURLが返ってきてしまい、対象の記事にアクセスできません。そこで各記事に対応した形のURLにするために置換作業を行います。

functions.php
function custom_posttype_permalink($post_link, $id = 0, $leavename) {

    global $wp_rewrite;

    $post = &get_post($id);

    if(is_wp_error( $post )){
        return $post;
    }

    if('books' === $post->post_type){
        $newlink = $wp_rewrite->get_extra_permastruct($post->post_type);

        $newlink = str_replace('%books%', $post->post_type, $newlink);

        $newlink = str_replace('%post_id%', $post->ID, $newlink);

        $newlink = home_url(user_trailingslashit($newlink));

        return $newlink;
    }

    return $post_link;
}

4.リライトルールを更新する

最後にwordpressの管理画面の[設定]-[パーマリンク設定]で更新ボタンを押下します。
この手順を実施しないと、出力されているURLは正しいけれどリンクは切れている、という状態に陥るため忘れずにやりましょう。

68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3136353135362f36383332636137372d623431322d336138352d643565382d3330346433613731333930382e6a706567.jpg

5.確認

以下の手順を全て実施すると、画像のようになります。
また、今回は「books」に限定したため、他のカスタム投稿タイプ(ここでは「movies」としています)のパーマリンクには変化がないことが分かります。

[before]
1.jpg

[after]
2.jpg

[そのほかのカスタム投稿タイプ]
3.jpg

4.最後に

パーマリンクを変更すると、以前のパーマリンクttps://example.com/カスタム投稿タイプ名/スラッグはリンク切れとなるので、注意が必要です。
記事の冒頭でも記載しましたが、ほかにいい方法を知っているぞ!という方はお教えいただければと思います。

5.参考にした記事一覧

Rewrite API/add rewrite rule - WordPress Codex 日本語版

[WordPress] カスタム投稿タイプのリライトに関するまとめ

WordPressのカスタム投稿タイプを企業サイトに使う場合の(超個人的)決定版