この記事は最後に更新してから1年以上経過しています。

適切なテンプレートファイルを用意してテンプレート内の振り分け処理を無くす

説明

/wp-includes/template-loader.phpではリクエストされたページに応じて現在のテーマにあるテンプレートファイルの中から適切なものを選びに振り分けている。ここでは、さまざまなテンプレートファイルの種類と、テンプレートファイルが省略された場合の内部の動作についてまとめてみる。

テンプレートファイルの優先順位

テンプレートファイルの種類はバージョンによって異なり、次に示す優先度で適用される。
優先度条件テンプレート
1is_embed() embed-{$post_type}-{$post_format}.php
embed-{$post_type}.php
embed.php
2is_404() 404.php
3is_search() search.php
4is_front_page() front-page.php
5is_home() home.php
index.php
6is_privacy_policy() privacy-policy.php
7is_post_type_archive() archive-{$post_type}.php
archive.php
※投稿タイプがアーカイブ有効時のみ
8is_tax() taxonomy-{$taxonomy}-{$tax_slug_decoded}.php
taxonomy-{$taxonomy}-{$tax_slug}.php
taxonomy-{$taxonomy}.php
taxonomy.php
9is_attachment() {$mime_type}-{$mime_subtype}.php
{$mime_subtype}.php
{$mime_type}.php
attachment.php
10is_single() 投稿ページ固有のテンプレート
single-{$post_type}-{$post_name_decoded}.php
single-{$post_type}-{$post_name}.php
single-{$post_type}.php
single.php
11is_page() 固定ページ固有のテンプレート
page-{$post_name_decoded}.php
page-{$post_name}.php
page-{$post_id}.php
page.php
12is_singular() singular.php
13is_category() category-{$cat_slug_decoded}.php
category-{$cat_slug}.php
category-{$cat_id}.php
category.php
14is_tag() tag-{$tag_slug_decoded}.php
tag-{$tag_slug}.php
tag-{$tag_id}.php
tag.php
15is_author() author-{$author_nicename}.php
author-{$author_id}.php
author.php
16is_date() date.php
17is_archive() archive-{$post_type}.php
archive.php
18その他 index.php
優先度条件テンプレート
1is_embed() embed-{$post_type}-{$post_format}.php
embed-{$post_type}.php
embed.php
2is_404() 404.php
3is_search() search.php
4is_front_page() front-page.php
5is_home() home.php
index.php
6is_post_type_archive() archive-{$post_type}.php
archive.php
※投稿タイプがアーカイブ有効時のみ
7is_tax() taxonomy-{$taxonomy}-{$tax_slug_decoded}.php
taxonomy-{$taxonomy}-{$tax_slug}.php
taxonomy-{$taxonomy}.php
taxonomy.php
8is_attachment() {$mime_type}-{$mime_subtype}.php
{$mime_subtype}.php
{$mime_type}.php
attachment.php
9is_single() 投稿ページ固有のテンプレート
single-{$post_type}-{$post_name_decoded}.php
single-{$post_type}-{$post_name}.php
single-{$post_type}.php
single.php
10is_page() 固定ページ固有のテンプレート
page-{$post_name_decoded}.php
page-{$post_name}.php
page-{$post_id}.php
page.php
11is_singular() singular.php
12is_category() category-{$cat_slug_decoded}.php
category-{$cat_slug}.php
category-{$cat_id}.php
category.php
13is_tag() tag-{$tag_slug_decoded}.php
tag-{$tag_slug}.php
tag-{$tag_id}.php
tag.php
14is_author() author-{$author_nicename}.php
author-{$author_id}.php
author.php
15is_date() date.php
16is_archive() archive-{$post_type}.php
archive.php
17その他 index.php
優先度条件テンプレート
1is_embed() embed-{$post_type}-{$post_format}.php
embed-{$post_type}.php
embed.php
2is_404() 404.php
3is_search() search.php
4is_front_page() front-page.php
5is_home() home.php
index.php
6is_post_type_archive() archive-{$post_type}.php
archive.php
※投稿タイプがアーカイブ有効時のみ
7is_tax() taxonomy-{$taxonomy}-{$tax_slug}.php
taxonomy-{$taxonomy}.php
taxonomy.php
8is_attachment() {$mime_type}-{$mime_subtype}.php
{$mime_subtype}.php
{$mime_type}.php
attachment.php
9is_single() single-{$post_type}-{$post_name}.php
single-{$post_type}.php
single.php
10is_page() 固定ページ固有のテンプレート
page-{$post_name}.php
page-{$post_id}.php
page.php
11is_singular() singular.php
12is_category() category-{$cat_slug}.php
category-{$cat_id}.php
category.php
13is_tag() tag-{$tag_slug}.php
tag-{$tag_id}.php
tag.php
14is_author() author-{$author_nicename}.php
author-{$author_id}.php
author.php
15is_date() date.php
16is_archive() archive-{$post_type}.php
archive.php
17is_paged() paged.php
18その他 index.php
優先度条件テンプレート
1is_404() 404.php
2is_search() search.php
3is_front_page() front-page.php
4is_home() home.php
index.php
5is_post_type_archive() archive-{$post_type}.php
archive.php
※投稿タイプがアーカイブ有効時のみ
6is_tax() taxonomy-{$taxonomy}-{$tax_slug}.php
taxonomy-{$taxonomy}.php
taxonomy.php
7is_attachment() {$mime_type}-{$mime_subtype}.php
{$mime_subtype}.php
{$mime_type}.php
attachment.php
8is_single() single-{$post_type}-{$post_name}.php
single-{$post_type}.php
single.php
9is_page() 固定ページ固有のテンプレート
page-{$post_name}.php
page-{$post_id}.php
page.php
10is_singular() singular.php
11is_category() category-{$cat_slug}.php
category-{$cat_id}.php
category.php
12is_tag() tag-{$tag_slug}.php
tag-{$tag_id}.php
tag.php
13is_author() author-{$author_nicename}.php
author-{$author_id}.php
author.php
14is_date() date.php
15is_archive() archive-{$post_type}.php
archive.php
16is_comments_popup() comments-popup.php
17is_paged() paged.php
18その他 index.php
優先度条件テンプレート
1is_404() 404.php
2is_search() search.php
3is_front_page() front-page.php
4is_home() home.php
index.php
5is_post_type_archive() archive-{$post_type}.php
archive.php
※投稿タイプがアーカイブ有効時のみ
6is_tax() taxonomy-{$taxonomy}-{$tax_slug}.php
taxonomy-{$taxonomy}.php
taxonomy.php
7is_attachment() {$mime_type}-{$mime_subtype}.php
{$mime_subtype}.php
{$mime_type}.php
attachment.php
8is_single() single-{$post_type}-{$post_name}.php
single-{$post_type}.php
single.php
9is_page() 固定ページ固有のテンプレート
page-{$post_name}.php
page-{$post_id}.php
page.php
10is_category() category-{$cat_slug}.php
category-{$cat_id}.php
category.php
11is_tag() tag-{$tag_slug}.php
tag-{$tag_id}.php
tag.php
12is_author() author-{$author_nicename}.php
author-{$author_id}.php
author.php
13is_date() date.php
14is_archive() archive-{$post_type}.php
archive.php
15is_comments_popup() comments-popup.php
16is_paged() paged.php
18その他 index.php

具体的な例で説明すると、スラッグが'news'(カテゴリーidが21)というカテゴリーアーカイブページ(リクエストURLがhttp://localhost/category/news)がリクエストされたとしよう。その場合、テーマ内の category-news.php → category-21.php → category.php → archive.php → index.php の順にファイルが存在するか調べられ、最初に見つかったテンプレートファイルがリクエストに応答する(対象の投稿内容を表示する)ことになる。

フロントページ(トップページ)の優先順位

フロントページは、 is_front_page関数で行い、その後で is_home関数によって判断しており、管理者ページの「設定」「表示設定」「フロントページの表示」の指定によって振る舞いが変わる。この振る舞いのパターンは次の3種類である。

設定が「最新の投稿」になっている場合、テンプレートファイルの参照順は front-page.php → home.php → index.php の順になる。
設定が「固定ページ」で「フロントページ」が選択されて場合、 front-page.php → page.php → index.php の順になる。
設定が「固定ページ」で「投稿ページ」が選択されて場合、 home.php → index.php の順になる。

添付ファイルはMIMEタイプで振り分けできる

投稿タイプが添付ファイルのページは、attachment.php → index.phpの順に対応するが、添付ファイルのMIMEタイプに応じて個別のテンプレートファイルで対応することができる。MIMEタイプは「image/jpeg」の形式でファイルの種類を示すもので、このMIMEタイプであればテンプレートファイルは、image.php → jpeg.php → image_jpeg.php で対応することになる。実際、標準テーマ「TwentyEleven」では image.php が用意されているので、作り方はそちらを参考にするといい。

このMIMEタイプによるテンプレートファイルだが、今の参照順だとMIMEサブタイプの対応が多少注意が必要かもしれない。例えば標準テーマ「TwentyEleven」でJPEGファイル「image/jpeg」とPNGファイル「image/png」で異なる表示にする場合、すでに image.php が存在するため、jpeg.php や png.php を用意してもそれらの前に image.php が見つかってしまうため、そのままでは jpeg.php や png.php は有効にならない。簡単な対策としては、image.php を無くすことだが、その場合は他のイメージファイルの対応をどうするかという問題が生じる。
MIMEタイプのテンプレートファイルの参照順については、image_jpeg.php → jpeg.php → image.php のようにサブタイプ名を含んだテンプレートファイルから参照する方がより柔軟に対応できると思う。

固定ページは専用テンプレートファイルを指定できる

固定ページは、page.php → index.php の順に参照されるが、ほとんどは page.php で対応し、特定の固定ページについても page.php 内で表示内容を切り替えている方が多いのではないだろうか。
今回この記事をまとめる中での最大の発見は、投稿名(スラッグ)または投稿IDを指定することで、その固定ページ専用のテンプレートファイルを指定できるところ。例えば、固定ページに「about」という投稿名を付けた場合は、page-about.php を用意すればいい。これで page.php の中から表示内容を切り分け処理はなくなり、コードもすっきりする。

追記: get_page_template_slug関数で取得できる専用テンプレートファイルが指定されている場合はそれが最優先され、その後に投稿名(スラッグ)または投稿IDを含んだテンプレートファイルが順次適用されることになる。

追記:4.3.0では投稿(single)と固定ページ(page)の共通テンプレートsingular.phpが利用できるようになった。これにより、投稿(single)と固定ページ(page)が同じデザインの場合はsingle.phpとpage.phpを用意せず、singular.phpのみを用意すればよい。

4.4以降なら投稿ページでも専用テンプレートファイルを指定できる

従来の投稿ページは、single-{投稿タイプのスラッグ}.php → single.php → index.php の順に参照される。上記のように、固定ページば専用テンプレートファイルを指定できるが、投稿ページは標準では対応できなかった。
4.4からは投稿ページであっても専用テンプレートファイルを利用できるように変更された。具体的には、single-{投稿タイプのスラッグ}.php の前に single-{投稿タイプのスラッグ}-{投稿名}.php が優先されるようになり、特定の投稿ページで専用テンプレートファイルを利用できる。

追記:4.7.0では固定ページと同じように get_page_template_slug関数で取得できる専用テンプレートファイルが指定されている場合はそれが最優先される。

カスタムタクソノミーは taxonomy.php で

カテゴリーや投稿タグ以外のタクソノミーとしてカスタムタクソノミー(任意のタクソノミー)を登録できるようになっているが、taxonomy.php はそれらカスタムタクソノミーのアーカイブページ用の代表的なテンプレートファイルである。カスタムタクソノミーのテンプレートファイルは、taxonomy-{taxonomy}-{slug}.php → taxonomy-{taxonomy}.php → taxonomy.php → archive.php → index.php の順にファイルが存在するか調べられる。注意する点は、カテゴリーや投稿タグのようにタクソノミーIDを指定したテンプレートファイルがないところだろう(WordPress 3.2.1)。
ちなみにカスタムタクソノミーかどうかの判断は、 is_tax関数で調べることができ、archive.php で表示内容を切り分ける場合はこのis_taxを利用するとよいだろう。

このようにテンプレートファイルを整理してみると、その種類の多さを再認識させられた。表示内容が共通するところは上位レベルのテンプレートファイルで対応し、特定の条件のみで表示を切り替えなければならない時は下位レベルのテンプレートで対応することで、より効率よく、メンテナンス性の高いテーマを作成できる。テーマを作成する際は、どのリクエストの場合に下位レベルのテンプレートファイルを使用するかをきちんと考慮して設計したいものだ。


最終更新 : 2019年05月24日 15:35


お勧め

delete_post_meta(2018年5月27日 更新)

bool delete_post_meta( int $post_id, string $meta_key [ , mixed $meta_value = '' ] )
投稿情報のカスタムフィールド情報を削除する。

wp_is_numeric_array(2018年5月27日 更新)

bool wp_is_numeric_array( mixed $data )
数値キーのみの配列か調べる。

get_tag_regex(2013年8月3日 更新)

string get_tag_regex( string $tag )
HTMLタグの正規表現パターンを取得する。

get_all_page_ids(2012年5月30日 更新)

array get_all_page_ids( )
全ページ(post_typeが'page')の投稿IDを取得する。

the_post_thumbnail_caption(2018年5月27日 更新)

void the_post_thumbnail_caption( mixed $post = null )
投稿ページのサムネイル(アイキャッチ画像)キャプションを表示する。