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

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

説明

/wp-includes/template-loader.phpではリクエストされたページに応じて現在のテーマにあるテンプレートファイルの中から適切なものを選びに振り分けている。ここでは、さまざまなテンプレートファイルの種類と、テンプレートファイルが省略された場合の内部の動作についてまとめてみる。
テンプレートファイルの優先順位
テンプレートファイルの種類を整理すると、次のような優先度で適用される4階層に分類できる
優先度条件 Ver 4.7.0 Ver 4.5.0 Ver 4.3.0 Ver 3.7.0
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
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
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
固定ページ固有のテンプレート
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
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
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_comments_popup() 未サポート 未サポート comments-popup.php
18is_paged() 未サポート paged.php
19その他 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を利用するとよいだろう。

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

関連

  • get_page_template_slug - 固定ページに指定されているテンプレートファイルのスラッグを取得する
  • is_front_page - フロントページか調べる
  • is_home - ホームページか調べる
  • is_tax - タクソノミーアーカイブページか調べる

お勧めコンテンツ

is_main_query(2012年3月5日 登録)

bool is_main_query( )
現在の投稿情報が最初に検索されたものか調べる。

add_theme_page(2011年5月26日 登録)

mixed add_theme_page( string $page_title, string $menu_title, mixed string $capability, string $menu_slug [ , mixed $function = '' ] )
外観メニューにサブメニューを登録する。

get_bookmark(2011年6月10日 登録)

mixed get_bookmark( mixed $bookmark [ , string $output = OBJECT [ , string $filter = 'raw' ] ] )
リンク情報を取得する。

get_footer(2009年11月12日 登録)

void get_footer( [ string $name = null ] )
フッターパーツを記述したメインフッターファイルfooter.php(またはサブフッターファイルfooter-???.php)を読み込む。

has_excerpt(2011年4月22日 登録)

bool has_excerpt( [ int $id = 0 ] )
投稿情報に抜粋が含まれている(入力されている)か調べる。

最終更新日時 : 2016-12-15 19:16