WordPress の single.php を投稿フォーマットで振り分ける方法

March 31, 2015

投稿フォーマットに応じてシングル ページのテンプレート(single.php)を切り替える方法です。また、この方法を応用すると、任意の条件で振り分けて任意のテンプレートを読み込むことができます。

Post Format Specific single.php Template in WordPress

例えば、投稿フォーマットが「video」の記事は、single.php ではなく、single-video.php が読み込まれるようにしたい場合に使います。

以下のコードを functions.php に追加します。

function add_post_format_template( $single_template ) {
	$new_template = $single_template;

	$post = get_queried_object();
	$post_format = get_post_format( $post );

	$single_post_format_template = locate_template( "single-{$post_format}.php" );
	if( !empty( $single_post_format_template ) )
		$new_template = $single_post_format_template;

	return $new_template;
}

add_filter( 'single_template', 'add_post_format_template' );

投稿フォーマットに対応する single-xxxxx.php ファイルが無い場合はデフォルトの振り分けが有効になりますので心配ありません。ちなみに、locate_template() 関数にてファイルの存在チェックがされています。

プチ解説

通常、投稿フォーマットのテンプレート振り分けは、single.php 内の get_template_part() 関数で実現されています。

get_template_part( 'content', get_post_format() );

標準の投稿は content.php、投稿フォーマット「video」なら content-video.php、投稿フォーマット「image」なら content-image.php が読み込まれます。普通ならこれで十分だと思います。

普通では飽き足らず、投稿フォーマットによって header.php や footer.php を含めてテンプレートを全面的に切り替えたい場合に、本稿の方法がマッチします。

single_template フィルター フック

single.php や category.php などの WordPress コア部分のテンプレート読み込みをフックするフィルターが用意されています。single.php の場合は single_temlate フィルター フックです。get_query_template() という関数で定義されています。詳細は以下 Codex をご参照ください(日本語版は未翻訳です)。

同種のフィルター フックとデフォルトの振り分け

single_template フィルター フックと同様に、category_template や page_template など、{$type}_template フィルター フックが用意されています。

これらを使う前に、まずは Codex のテンプレート階層 概観図を参照してデフォルトの振り分けを確認するのが良いと思います。

(応用)特定のカテゴリのみ single.php を振り分ける方法

例えば、記事(投稿)が cinema というスラッグのカテゴリに属しているとき single-cinema.php に振り分けるコードは以下です。

function add_category_cinema_template( $single_template ) {
	$new_template = $single_template;

	$post = get_queried_object();
	if ( has_category( 'cinema', $post ) ) {
		$single_cinema_template = locate_template( 'single-cinema.php' );
		if( !empty( $single_cinema_template ) )
			$new_template = $single_cinema_template;
	}

	return $new_template;
}

add_filter( 'single_template', 'add_category_cinema_template' );

尚、WordPress では一つの記事が複数の異なるカテゴリに属することができます。カテゴリでテンプレートを振り分ける際には注意が必要です。

カスタム投稿タイプとの関連性

カスタム投稿タイプなら、single.php の切り替えにデフォルトで対応しています。例えば「movie」というカスタム投稿タイプを作成すると、シングル ページのテンプレートとして自動的に single-movie.php を呼び出してくれます。しかし、カスタム投稿タイプは、投稿フォーマットに比べて大掛かりなので、テンプレートだけ変えたいなら本稿のやり方も選択肢になると思います。

筆者はカスタム投稿タイプについては よく理解していませんので、比較検討の際は以下の良さげなページをご参照くださいませ。

あとがき

実は筆者、この方法にたどり着くまでに 3時間くらい掛かりました。サジェストに導かれるまま「single.php 振り分け」や「single.php 条件分岐」で検索すると、上位陣は またもやコピペ記事ばかり。しかも、single.php 内で include するというファンキーな方法です。グーグル先生、WordPress 界隈の闇は深いですね。

4 thoughts on “WordPress の single.php を投稿フォーマットで振り分ける方法

  1. Pingback: 投稿フォーマットで条件分岐してアイキャッチ画像を出し分ける方法 | 雑記 BOOOKs

  2. Pingback: WordPress:特定のカテゴリのみテンプレートを振り分ける | hacknote

  3. 吉田

    こんにちは。えー。もしも他のみなさんにもお役に立つのであれば、このコメントや返信は公開してください。公開しても個別に返信いただいても構いませんが、質問と相談にのっていただければ嬉しく思います。私も同じように、テンプレートをカテゴリ別にふりわけたいなと思い、1年経ちました。勉強不足なのもあるのでしょうけれど、確かに否定はしませんが、本当に難しい課題で頭を痛めています。それで上記のコードを試したところ、テンプレートを振り分けることができて感動しました・・・・が、テンプレートを複数振り分けるのは・・・・、難しいです。是非お知恵をわけていただきたきたいなと、相談のメールでございます。確かに私も調べて上位記事?はコピペ記事ばかりで、どなたかに聞いたら、「デバッグ」を勉強してくださいと返信が来ました。   確かに、勉強すれば良いのでしょうけれど・・・。   よろしく良い返信をご検討ください!  

    Reply

コメントを残す

メールアドレスが公開されることはありません。