カスタム投稿とカスタムタクソノミーを追加した場合、デフォルトの状態ではURLは別階層に分かれた状態で表示されます。
例えば、「news」というカスタム投稿を追加し、「news_cat」というカスタムタクソノミーを追加した場合、カスタム投稿とカスタムタクソノミー一覧のURLはそれぞれ以下のようになります。
- カスタム投稿 → /news/投稿名/
- カスタムタクソノミー → /news_cat/ターム名/
できれば、カスタムタクソノミーを「/news/news_cat/ターム名/」というURLに変更したいというケースがあるかもしれません。(実際に、カスタム投稿とカスタムタクソノミーでURLのディレクトリが異なるのは気になるから調整してほしいと言われたことがあります)
そこで今回は、カスタム投稿とカスタムタクソノミーを追加した時に、URLのディレクトリ構造を揃える方法をご紹介いたします。
カスタムタクソノミーのURLを調整してカスタム投稿の下の階層で表示させる方法
※カスタム投稿は「news」、カスタムタクソノミーは「news_cat」として解説しています。カスタム投稿名およびタクソノミー名は適宜変更してください。
ステップ1. カスタム投稿とカスタムタクソノミーの追加
まずは、適用しているテーマのfunctions.phpに以下を記述し、カスタム投稿とカスタムタクソノミーを追加します。
function add_custom_post_type() {
$args = array(
'label' => 'ニュース', //カスタム投稿のラベル
'hierarchical' => false, //階層構造の有無
'public' => true, //投稿の公開
'menu_position' => 5, //メニューの位置
'has_archive' => true, //アーカイブの生成
'show_in_rest' => true, //Gutenberg(ブロックエディタ)に対応
'rewrite' => array('with_front' => false), //URLから共通設定のパーマリンクを除外
'supports' => array(
'title', //タイトルを有効化
'editor', //本文を有効化
'thumbnail' //アイキャッチ画像の有効化
)
);
register_post_type( 'news', $args );
$tax_args = array(
'hierarchical' => true, //階層構造の有無。falseでタグ形式
'label' => 'ニュースカテゴリー', //タクソノミーのラベル
'show_ui' => true, //タームを管理するためにデフォルトのUIを用意
'show_admin_column' => true, //管理画面の投稿一覧に表示
'query_var' => true, //アーカイブを作成
'show_in_rest' => true, //Gutenberg(ブロックエディタ)に対応
'rewrite' => array('slug' => 'news/news_cat', 'with_front' => false)
);
register_taxonomy( 'news_cat', 'news', $tax_args );
}
add_action( 'init', 'add_custom_post_type' );
カスタムタクソノミーを追加する時に、「’rewrite’ => array(‘slug’ => ‘news/news_cat’, ‘with_front’ => false)」を記述し、スラッグを変更しています。
ステップ2. add_rewrite_ruleの追加
このままだとまだ「/news/news_cat/ターム名」にアクセスしても表示できません。
functions.phpにadd_rewrite_ruleを追加して、「/news/news_cat」にアクセスされた場合はnews_catの一覧ページを表示するように調整します。
function url_rewrite_rules() {
add_rewrite_rule('news/news_cat/([^/]+)/page/([0-9]+)/?$', 'index.php?news_cat=$matches[1]&paged=$matches[2]', 'top');
}
add_action( 'init', 'url_rewrite_rules' );
「/page/([0-9]+)/」と「&paged=$matches[2]」の部分は、ページネーションで2ページ目以降へ移動した時に404にならないようにするための対策です。
ステップ3. タームリンクの調整
add_rewrite_ruleでURLをリライトすることで、指定したURLでカスタムタクソノミーの一覧ページへアクセスできるようになります。しかし、get_termsなどで取得されるリンクは元のまま(/news_cat/ターム名/)です。
そこで、各タームのURLを変更するために、term_linkというフックを使ってURLを書き換えます。具体的には、functions.phpに以下のように追記します。
function rewrite_term_links($termlink, $term, $taxonomy) {
return ($taxonomy === 'news_cat' ? home_url('/news/news_cat/'. $term->slug) : $termlink);
}
add_filter( 'term_link', 'rewrite_term_links', 10, 3 );
これで、get_termsなどによって取得されるリンク先は、add_rewrite_ruleで書き換えたURLと同じように「/news/news_cat/ターム名/」に変わります。
ステップ4. パーマリンク設定の再保存
最後に[設定] – [パーマリンク設定]を開き、何も変更せずに保存をクリックします。これでパーマリンクがflushされて、リライトしたスラッグでタクソノミーの一覧ページを表示できるようになります。
あとがき
どうしてもURLを調整したい時は、add_rewrite_ruleを駆使して変更しましょう。ちなみに、個人的にはここまでやる必要はないのかなと思っています。
カスタムタクソノミーは複数の投稿タイプで使用することができます。今回のようにタクソノミーを1つの投稿タイプでしか利用しないのであれば、投稿タイプの下の階層で表示させるのは良いと思います。ですが、後から他の投稿タイプでも使うことになった場合はURLに違和感が出てしまいますね。
URLにこだわって工数を割くよりもコンテンツに力を入れた方が賢いです。