この記事は最後に更新してから1年以上経過しています。
説明
少し前に投稿した「適切なテンプレートファイルを用意してテンプレート内の振り分け処理を無くす」で説明した通り、特定のカテゴリ専用のテンプレートとしてcategory-○○.phpを用意することで、category.phpやarchive.php内で振り分けを行う必要がなくなる。ただ、すべてのカテゴリ分を用意するのは効率的ではないし、特に子カテゴリについては親カテゴリと共通内容になるケースが多いのではないだろうか。ここでは、子カテゴリの個別テンプレートファイルを作らず、親カテゴリのテンプレートを利用する方法を紹介する。カテゴリのテンプレートファイルがない場合の振る舞い
以前の投稿のおさらいを兼ねて、カテゴリのテンプレートファイルがどのように検索されるかを整理する。WordPressのシステムではユーザのリクエストがカテゴリページの場合、次の順番でテーマ内のテンプレートファイルを検索し、最初に見つかったテンプレートファイルを読み込んで、リクエストに応答する。
1.category-slug.php ※slugはカテゴリのスラッグ
2.category-id.php ※idはカテゴリのID
3.category.php
4.archive.php
5.index.php
例えば、'ニュース'というカテゴリのスラッグが'news'でIDが10の場合、WordPressシステムではcategory-news.php → category-10.php → category.php → category.php → index.phpの順で検索し、最初に見つかったテンプレートファイルが適用される。この振る舞いは子カテゴリの場合も同様である。
子カテゴリのテンプレートファイルがない場合は親カテゴリのテンプレートファイルを使う
今回紹介するケースは、複数のカテゴリがあり、その中には親子関係のカテゴリが含まれている。さらに、子カテゴリについてはテーマ提供後に追加される可能性があるとしよう。このようなケースの対応を考えた場合、通常であればcategory.phpかarchive.phpの内部で振り分けることになるだろう(子カテゴリを追加した際に、その子カテゴリ用のテンプレートファイルを追加できるのならそれでもいいのだが……)。
こんな時、子カテゴリの表示内容が親カテゴリの表示内容と大きく違いがないならば、子カテゴリ(さらに孫カテゴリも)の表示については、親カテゴリのテンプレートファイルと共通にして対応できればかなり効率的だろう。つまり、子カテゴリについては専用のテンプレートファイルを作らず、親カテゴリのテンプレートを使うというものだ。
通常、前述の通り子カテゴリのスラッグまたはIDを付与した専用テンプレートファイルがない場合はcategory.php→archive.php→index.phpの何れかが適用さえるのだが、以下のコードをfunctions.phpに記述することで専用テンプレートファイルがない場合に親(さらにその親も)カテゴリのテンプレートファイルが利用可能になる。
add_filter( 'category_template', 'my_category_template' );
function my_category_template( $template ) {
$category = get_queried_object();
if ( $category->parent != 0 &&
( $template == "" || strpos( $template, "category.php" ) !== false ) ) {
$templates = array();
while ( $category->parent ) {
$category = get_category( $category->parent );
if ( !isset( $category->slug ) ) break;
$templates[] = "category-{$category->slug}.php";
$templates[] = "category-{$category->term_id}.php";
}
$templates[] = "category.php";
$template = locate_template( $templates );
}
return $template;
}
使用するフィルターは'category_template'。名前でわかる通りリクエストがカテゴリページの場合に対応するテンプレートファイルを選択する際に使用されているフィルターである。このフィルターに対応する関数のパラメータ$templateには、テーマ内にテンプレートファイルがある場合はそのパス名が、なかった場合は''が設定されてくる。普通にテーマを作っているなら、カテゴリの専用テンプレートファイルまたは'category.php'のパス名になるだろう。
上記処理では、リクエストされたカテゴリページのカテゴリが子カテゴリ(親カテゴリを持つ)場合、$templateが専用テンプレートファイルのパス名でない(テンプレートファイルが見つからない、または'category.php'のケース)ならば、親カテゴリのテンプレートがあるかを調べている。また直接の親カテゴリだけでなく、その親カテゴリも調べる対象にしており、よりリクエストされたカテゴリに近い親カテゴリのテンプレートファイルを検索するようにしている。
と、久しぶりにサイト構築でこのようなケースに遭遇したので、事例として紹介しました。フィルター処理中に登場した get_queried_object関数だが、WordPress 3.1.0で提供されたもの。ここではリクエストされたカテゴリ情報を取得しているが、アーカイブページのデータ取得する場合など幅広く使えそうだ。
最終更新 : 2011年12月08日 13:56
関連
お勧め
parse_blocks(2024年7月24日 更新)
single_post_title(2012年9月6日 更新)
timer_stop(2021年7月23日 更新)
is_ssl(2022年7月2日 更新)
wp_title_rss(2014年4月10日 更新)