WordPressでは、投稿タイプやページによってテンプレートファイルを分けることができますが、さらに「投稿に属するカテゴリー」に応じてテンプレートを切り替えたい場面もあります。たとえば、「ニュース」と「ブログ」でレイアウトを変えたい場合などに有効です。
テンプレート切り替えの基本:single_templateフィルターを使用
カテゴリーごとにテンプレートを切り替えるには、functions.phpに以下のコードを追加します。このコードは、投稿が属するカテゴリーに応じて、該当するテンプレートファイルを動的に読み込みます。
function custom_single_template_by_category($template) {
if (is_single()) {
global $post;
$categories = get_the_category($post->ID);
if (!empty($categories)) {
$category_slug = $categories[0]->slug; // 名前順で最初のカテゴリーを取得
$custom_template = locate_template("single-cat-{$category_slug}.php");
if ($custom_template) {
return $custom_template;
}
}
}
return $template;
}
add_filter('single_template', 'custom_single_template_by_category');
テンプレートファイルの命名規則
上記のコードでは、カテゴリーのスラッグをもとにsingle-cat-{スラッグ}.phpを読み込みに行きます。たとえば、以下のようなテンプレートファイルを作成することで、それぞれのカテゴリーに応じた表示が可能になります。
- single-cat-news.php(newsカテゴリ用)
- single-cat-blog.php(blogカテゴリ用)
該当するテンプレートファイルが存在しない場合は、通常のsingle.phpが使われます。
複数カテゴリに対応する場合の注意点
投稿が複数のカテゴリーに属している場合、$categories[0]がどのカテゴリーになるかに注意が必要です。
get_the_category()が内部で使うWP_Term_Queryのorderbyデフォルト値は'term_id'ではなく‘name’(名前順)です(公式リファレンスで確認)。つまり$categories[0]が指すのは「IDが最も若いカテゴリー」ではなく、名前が五十音・アルファベット順で最初に来るカテゴリーです。作成日時やID順で優先カテゴリーを決めたい場合は、以下のように明示的に並べ替えてください。$categories = get_the_category($post->ID);
usort($categories, function ($a, $b) {
return $a->term_id <=> $b->term_id;
});
$category_slug = $categories[0]->slug; // IDが最も若いカテゴリーを取得
複数カテゴリ対応の優先順位をさらに細かく制御したい場合は、foreachを使って特定のスラッグを検索する形に変更することも可能です。
特定のカスタム投稿タイプと組み合わせる場合
カスタム投稿タイプのみに適用したい場合は、条件分岐にget_post_type()を追加してください。
if (is_single() && get_post_type() === 'your_custom_post_type') {
// 以下同様の処理
}
よくある質問(FAQ)
まとめ
カテゴリーごとに投稿テンプレートを切り替えることで、同じ投稿タイプでもカテゴリの目的に応じたデザインを適用できます。ニュース、コラム、イベントなどでテンプレートを分けたいケースに非常に便利です。フィルターフックとlocate_template()を使えば、柔軟に管理でき、テーマの可読性も損ないません。複数カテゴリーに属する投稿では、優先カテゴリーの決め方を明示的にコントロールすることを忘れないようにしましょう。

