📚 本記事は、WordPressテーマの基礎から実践までを学べるシリーズの【第12回】です。
条件分岐やテンプレート階層は、この先の表示カスタマイズやACF活用にも不可欠な知識です。
WordPressテーマ開発で、避けて通れないのがテンプレート階層・条件分岐タグ・page.php/single.phpの使い分け。
page.php と single.php の違いがわからない…という初心者も、この記事でスッキリ整理できます!
✅ 今回のゴール
- 「page.phpとsingle.phpの違いがあやふや」な状態を卒業できる
- テンプレート階層を使って「表示切り替え」ができるようになる
- よく使う条件タグの使い分けが身につく
page.phpとsingle.phpの違いをテンプレート階層とともに解説
WordPressでは、表示するコンテンツの種類に応じて自動的にテンプレートが切り替わります。
- 固定ページ →
page.php
- 投稿 →
single.php
- カスタム投稿(例:
news
) →single-news.php
(なければsingle.php
)
📘 カスタム投稿にもテンプレート階層は適用されます:
投稿タイプ | 優先されるテンプレート |
---|---|
news | single-news.php → single.php |
voice | single-voice.php → single.php |
event | single-event.php → single.php |
投稿タイプが増えても、命名ルールを守れば簡単に対応できます。
💡 補足:テンプレート階層は「優先度順」の仕組み
▼ テンプレート階層の優先順を図解すると、以下のようになります:
page-about.php
└ page-{$id}.php
└ page.php
└ singular.php
└ index.php
👆 上の例では、ページスラッグが about
の場合に優先的に page-about.php
が使われ、なければ順に下位テンプレートにフォールバックされます。
条件分岐タグの基本
テンプレート内で「どのページか」を判定したいときに使えるのが「条件分岐タグ」です。
条件タグ | 意味 |
---|---|
is_home() | ブログのトップ(投稿一覧) |
is_front_page() | フロントページ |
is_page() | 固定ページ |
is_single() | 投稿(カスタム投稿含む) |
is_archive() | アーカイブ全般 |
is_post_type_archive() | カスタム投稿のアーカイブ |
is_attachment() | 添付ファイルページ |
is_search() | 検索結果ページ |
is_404() | 404エラーページ |
is_category() | カテゴリアーカイブ |
💡 補足:テンプレートファイル名で分岐したいときは?
is_page_template()
を使えば、固定ページに割り当てたテンプレートファイル名で処理を分けられます。
// 固定ページに特定テンプレート(template-contact.php)が割り当てられているかを判定
if (is_page_template('template-contact.php')) {
// お問い合わせページだけスクリプトを読み込む
}
💡 実案件では「特定ページだけ JavaScript を読み込む」といった使い方も便利です。たとえば:
// お問い合わせページ用のスクリプトを読み込む処理(ページテンプレートに応じて動的に制御)
function enqueue_contact_form_script() {
if (is_page_template('template-contact.php')) {
// contact-form.js をフッターで読み込む(依存関係なし、バージョンなし)
wp_enqueue_script('contact-form', get_template_directory_uri() . '/js/contact-form.js', [], false, true);
}
}
add_action('wp_enqueue_scripts', 'enqueue_contact_form_script'); // フロント側のスクリプト登録フック
💡補足:テンプレート名は get_page_template_slug()
で取得できます。
カスタムテンプレートの条件分岐に便利です。
テーマ内の template-contact.php
が対象となります。
複数テンプレートで分岐したい場合は in_array()
を使ってもOK!
// 現在の固定ページに割り当てられたテンプレートファイル名を取得
$tpl = get_page_template_slug();
// 「お問い合わせ」や「予約」テンプレートの場合だけ処理を実行
if (in_array($tpl, ['template-contact.php', 'template-reserve.php'])) {
// 特定のテンプレート群だけ処理を分岐
}
🧪 応用:カスタム投稿タイプでレイアウトを切り替える
🔸 template_include でテンプレートを差し替える
条件に応じて読み込むテンプレート自体を動的に変えたいときは、template_include
フィルターが便利です。
// カスタム投稿タイプ「voice」の表示時にテンプレートを強制的に切り替える
function switch_template_for_voice($template) {
if (is_singular('voice')) {
// テーマ内の single-voice.php を強制的に適用
return get_template_directory() . '/single-voice.php';
}
return $template;
}
add_filter('template_include', 'switch_template_for_voice'); // テンプレート選定フィルター
🎯 たとえば、voice投稿タイプだけまったく違う構成(スライダー付き・吹き出し表示など)にしたい場合に非常に有効です。
このようにして、投稿タイプに応じたテンプレートをPHPで柔軟に制御することも可能です。
📌 この方法は、404ページや検索結果ページのテンプレート変更にも応用できます。
// 404ページだけ独自テンプレートを適用
function custom_404_template($template) {
if (is_404()) {
return get_template_directory() . '/custom-404.php';
}
return $template;
}
add_filter('template_include', 'custom_404_template');
// 検索結果ページだけテンプレートを変更
function custom_search_template($template) {
if (is_search()) {
return get_template_directory() . '/custom-search.php';
}
return $template;
}
add_filter('template_include', 'custom_search_template');
テーマごとに個別テンプレートを差し込みたいときにとても便利です。
<?php if (is_singular('news')) : ?>
<!-- template-parts/single-news.php を読み込む(テンプレートパーツの再利用に便利) -->
<?php get_template_part('template-parts/single', 'news'); ?>
<?php else : ?>
<?php get_template_part('template-parts/single', 'default'); ?>
<?php endif; ?>
再利用可能なテンプレートパーツに分けておくと、他の投稿タイプやページでも同じ表示を使い回せるようになります。
これで「news投稿だけ違う見た目にする」といった柔軟な制御が可能になります。
💡 get_template_part()
を使う際は、template-parts/single-news.php
のように命名規則を決めておくと、整理しやすく再利用にも便利です。
また、存在確認しながらテンプレートを読み込みたい場合は、locate_template()
を使う方法もあります。
// 子テーマ → 親テーマの順でテンプレートファイルの存在を確認して取得
$template = locate_template('template-parts/single-voice.php');
if ($template) {
// テンプレートが存在する場合は読み込む
include $template;
} else {
// 存在しない場合はデフォルトテンプレートを読み込む
include get_template_directory() . '/template-parts/single-default.php';
}
💡 locate_template()
は、子テーマ→親テーマの順にテンプレートを探してくれるため、カスタマイズ性が高くおすすめです。
読み込み順:
子テーマ → 親テーマ → デフォルトテンプレート
【例】
template-parts/single-voice.php(子)
→ template-parts/single-voice.php(親)
→ template-parts/single-default.php(親)
🛠 よくあるミスと対策
is_page()
はループ外でも使えるが、ページによっては get_queried_object()
の方が確実な場合も。
// 現在表示中の投稿(固定ページ)オブジェクトを取得
$page = get_queried_object();
// スラッグ(post_name)が 'about' のページのみ処理
if ($page->post_name === 'about') {
// 「会社概要」ページだけ処理を変える
}
is_front_page()
と is_home()
の使い分けに注意!
if (is_front_page()) {
// 固定ページのトップ
} elseif (is_home()) {
// 投稿一覧(ブログトップ)
}
💡 補足:条件を組み合わせたいときは?
if (is_single() && has_category('news')) {
// 「投稿」で、かつ「newsカテゴリ」なら
}
&&
(かつ)や ||
(または)で自由に条件を組み合わせましょう!
📝 まとめ
page.php
は固定ページ用、single.php
は投稿用テンプレート- テンプレート階層を理解すると、表示制御の自由度が大幅に上がる
- 条件分岐タグでページごとの処理を出し分けよう!
ちなみに、カスタム投稿や条件分岐を極めていくと、投稿ごとに違う情報を出し分ける場面も増えてきます。
そこで重要になるのが「カスタムフィールド」。
🧩 本記事で登場した主な関数・条件タグ:get_template_part()
, locate_template()
, template_include
, is_page()
, is_single()
, is_page_template()
, get_page_template_slug()
, is_404()
, is_search()
など
🚫 ちなみに、single.phpやpage.phpに条件を直接ベタ書きしすぎると、管理しにくくなりがちです。テンプレートパーツや階層構造をうまく活用して保守性を高めましょう。
🔮 次回予告
第13回では、投稿ページでのメタ情報の表示やカスタムフィールドの活用術を紹介予定です。
クライアント案件でもよくある「詳細ページのカスタマイズ」に踏み込みます!