カテゴリごとに違うsingle.phpを表示する方法【WordPress】

この記事の前提条件

対象: WordPress(テーマファイルの編集ができる環境)
難易度: ★★★
所要時間: 約15分

「お知らせ」カテゴリと「事例紹介」カテゴリで、投稿詳細ページのレイアウトを丸ごと変えたい…といったカスタマイズ要望、実務でよくあります。ただし、WordPressのテンプレート階層には「カテゴリごとの投稿詳細テンプレート」を自動で振り分けてくれる仕組みは、実は標準では用意されていません。ここを勘違いしていると、ファイルを用意しても読み込まれず時間を溶かしてしまいます。

⚠️ 「single-カテゴリスラッグ.php」という命名では動かない

投稿タイプごとのsingle-投稿タイプ.php(例: single-product.php)は自動で読み込まれますが、これはあくまで「投稿タイプ」単位の仕組みです。カテゴリ(タクソノミー)の一覧ページ用にはcategory-スラッグ.phpという命名が使えますが、投稿詳細ページ側にはこれに相当する自動振り分けの命名規則が存在しません。この勘違いによるつまずきは非常に多いです。

解決策: single_templateフィルターで振り分ける

自動振り分けの仕組みがない代わりに、single_templateというフィルターフックを使って、自分でテンプレートの振り分けルールを書きます。functions.phpに次のように記述します。

function switch_single_template_by_category( $template ) {
  if ( is_single() && in_category( 'news' ) ) {
    $new_template = locate_template( array( 'single-news.php' ) );
    if ( $new_template ) {
      return $new_template;
    }
  }
  return $template;
}
add_filter( 'single_template', 'switch_single_template_by_category' );

in_category('news')の部分で、対象にしたいカテゴリのスラッグを指定します。この条件に合致した投稿だけ、通常のsingle.phpではなくsingle-news.phpというファイルが読み込まれるようになります。ファイル名は任意ですが、分かりやすい名前を付けておきましょう。

1つの記事が複数カテゴリに属している場合の注意点

WordPressの投稿は複数カテゴリを同時に持てるため、ある記事が「お知らせ」と「事例紹介」の両方に属していた場合、どちらのテンプレートを優先するかを自分で決めておく必要があります。上記のコードはif文を上から順に評価するだけなので、優先したいカテゴリの条件分岐を先に書いておく、というルールを意識して実装しましょう。

まとめ

  • 投稿詳細ページには、カテゴリ名を使った自動振り分けの命名規則は存在しない
  • functions.phpでsingle_templateフィルターを使い、in_category()で条件分岐して振り分ける
  • 複数カテゴリに属する記事がある場合は、条件分岐の優先順位を意識して書く