🎮

WordPress でよく使うリライトルールをシンプルに書く

2023/05/14に公開

とはいえ、例示している程度のURL構造であれば、既存のプラグインを使った方が早くて確実。
Custom Post Type Permalinks

カスタム投稿タイプの URL に ID の数字を使う設定

デフォルトは投稿スラッグの文字列である。投稿 ID で表示したい場合の設定方法。

// 投稿タイプを登録
function my_post_type() {
    register_post_type(
        'news',
        array(
            'public' => true,
            'has_archive' => true,
            'rewrite' => array(
                             'with_front' => false,
                             'slug' => 'my-post-type'
            )
        )
    );
}
add_action( 'init', 'my_post_type' );

// /my-post-type/1234/ で投稿単体を表示するリライトルールを設定
function add_mypostype_rewrite_tag( $post_type ){
    if('my_post_type' === $post_type) {
        add_rewrite_tag(
	    '%my_post_type_id%',
	    '([0-9]+)',
	    'post_type=my_post_type&p=' );
        add_permastruct(
	    'my_post_type_id', // 第一引数を投稿タイプと同じにすると追加されない
	    'my-post-type/%my_post_type_id%' );
    }
}
add_action('registered_post_type', 'add_mypostype_rewrite_tag', 10, 1 );

// the_permalink() などで出力されるURLを変換
function my_post_type_link( $link, $post ){
    if ( 'my_post_type' !== $post->post_type ) {
        return $link;
    }
    return home_url( '/my-post-type/' . $post->ID );
}
add_filter( 'post_type_link', 'my_post_type_link', 1, 2 );

my_post_type_id という名前でパーマリンク構造を指定する。
既存のパーマリンクタグと重複しない名前にする。投稿タイプ名である my_post_type は投稿タイプ生成時にデフォルトで生成されるため使えない。

余談ながら、WordPress のコーディングルールからヨーダ記法を廃止する提案がなされている。
Proposal: Disallow assignments in conditions and remove the Yoda condition requirement for PHP – Make WordPress Core

投稿タイプに付与するタクソノミーのリライト設定

カスタム投稿タイプに専用タクソノミーを設定し、/<custom_post_type>/<term>/ としたい場合。

register_taxonomy(
    'my_taxonomy',
		array(
		    'public'          => true,
		    'show_ui'         => true,
		    'show_in_rest'    => true,
		    'capability_type' => 'my_post_type',
		    'rewrite'         => false,
     )
);
		             
add_action( 'init', function(){ 
    add_rewrite_tag( '%my_type_tax%','([^/]+', 'post_type=my_custom_type&my_taxonomy=' );
    add_permastruct( 'my_custom_type_term', '/my-post-type/%my_type_tax%', array( 'with_front'=>false));
}, 10)

/<custom_post_type>/my-taxonomy/<term>/ としたい場合は、タクソノミー登録時に 'rewrite'=>'my-post-type/my-taxnomy/ と設定する。別途でリライトルールを変える必要はない。

add_permastruct は 設定 → パーマリンク → パーマリンク構造→カスタム構造 で設定するのと同じである

オプションで、ページネーションをカバーするか選択できる(デフォルトではカバーする)ので、ページネーションのためのリライトルールを書かなくてよい。逆にページネーションのURLを WordPress デフォルトから変えたい場合は使えない、add_rewrite_rule() を使う。

add_permastruct() | Function | WordPress Developer Resources
add_rewrite_rule() | Function | WordPress Developer Resources

リライトルールの順序

リライトルールは概ね下記のグループである。グループごとにフィルターがある。
Rewrite API – WordPress Codex 日本語版

  • 照合される順序
    1. wp-sitemap.xml
    2. カスタム投稿タイプのアーカイブ関係
      • 投稿1タイプごとに
        2-1. フィード
        2-2. RSS
        2-3. ページネーション
    3. デフォルトのカテゴリー
    4. デフォルトのタグ
    5. add_permalink で挿入される位置
    6. register_post_type / register_taxonomy で登録される投稿タイプ・タクソノミー
    • カスタム投稿タイプのシングルページ関係とタクソノミーのグループ。グループ内の順序はコードを記述した順
    1. 固定ページ
    2. robots.txt / favicon.ico
    3. feed
    4. comment
    5. search
    6. 日付アーカイブ
    7. ルート向け

add_rewrite_rule は、このリライトルール配列の前に足すか、後ろに足すかである。

その他

無名関数だと remove_action() で外せなくなるが、リライトルールを他の処理で外すことは、まずないので無名関数でもいい。

add_action( 'init', function(){ ... }) 

下記コードが基本形、 my_type_tax というリライトタグは何の文字列を検出し、どんなクエリーを実行するか指定する。第2引数は正規表現、下記はスラッシュ以外の文字列にマッチする。この組み合わせで、投稿タイプが my_post_type かつ、正規表現でマッチした文字列のタームに属する投稿を探して表示する。

add_rewrite_tag( '%my_type_tax%', '([^/]+)', 'post_type=my_custom_type&my_taxonomy=' );

add_permastruct( 'my_custom_type_term', '/my-post-type/%my_type_tax%',
									 array( 'with_front' => false));

リライトルールの設定は、init アクションや、add_rewrite_rule でもいい。

{$permastructname}_rewrite_rules フィルターでリライトを追加する記述も妥当そうである。デフォルトでは使わないリライトルールを削除して、必要なルールを追加して返すこともできる。

my_post_type デフォルトのパーマリンク構造を変えるなら、

add_filter( 'my_post_type_rewrite_rules', functions($rules){ ... }, 10, 1 );

のようなフィルターでできるはず。コード例を見たことがないが。

Discussion