任意の名前のテンプレートで表示を行う方法
WordPressで任意の名前のテンプレートファイルを読み込む方法を紹介します。
WordPressデフォルトのテンプレート探索では、カテゴリ―を例にすると
「category-{$slug}.php」
「category-{$term_id}.php」
「category.php」
(「paged.php」)
「index.php」
となります。
例えば、「html」というスラッグのカテゴリ―を表示するページを別で作成したければ、「category-html.php」と命名したテンプレートを作成すれば良いというわけです。
しかし、なにかワケがあり、『「category-html.php」ではなく「html.php」で表示したい』という人向けの記事になっています。
デフォルトのテンプレートについて知りたい場合は「テンプレート階層」とでも調べれば出てくると思います。
テンプレート関連のフック
テンプレート読み込みの際に利用できるフックが4種類あります。
それぞれどのタイミングで実行されるのか見てみましょう。上から順に呼び出されます。
template_redirect
コア場所:「wp-includes/template-loader.php」
テンプレート探しをする際一番最初に呼ばれるアクションフックです。
根本からWordPressのテンプレート構造を使用したくない場合に便利です。
include等で目的のファイルを読み込んだ後はそのままWordPressのテンプレート探索の処理につながってしまいます。フックした関数内でexit等の終了処理をしましょう。
template_redirectで作成はされていないですが、ガッツリテンプレートを弄りたい場合は「Lightning」という公式のテーマを参考にすると良いと思います。(コード内コメントが日本語なので英語苦手な人でもわかりやすいかと思います。)
{$type}_template_hierarchy
コア場所:「wp-includes/template.php」
探すべきテンプレートファイル名を取得し終わった後に呼ばれるフィルターフックです。
この時点では読み込むファイルは決められておらず、引数の配列には優先度の高い順にテンプレート名が入っています。
子テーマ、親テーマにテンプレートを探しに行く前に変更したい場合はここで行います。
{$type}_template
コア場所:「wp-includes/template.php」
読み込むべきテンプレートが決定した後に呼ばれるフィルターフックです。
子テーマで見つかれば子テーマのテンプレートファイル、子テーマで見つからなければ親テーマのテンプレートファイルのパスを持っています。
強制的に親テーマのファイルを読み込ませたい場合などに使用できそうです。(そんな場面あるかな…)
template_include
コア場所:「wp-includes/template-loader.php」
テンプレートが「include」される直前に呼び出されるフィルターフックです。
上記の「 {$type}_template 」と実行タイミング的にはあまり変わりがありません。(間にほとんど処理がないという意味)
呼び出される直前なのでファイルパスさえ正しいものを渡せば、簡単にテンプレートを変更することが可能です。
今回は一番最後の「template_include」で変更する例を紹介したいと思います。
テンプレートの変更例
先ほど紹介したフックの中の「template_include」を使用して実際にテンプレートを変更したいと思います。
apply_filters( 'template_include', string $template )
引数には読み込むべきテンプレートのパスが含まれています。
なので返す値もテンプレートのパスを返してあげます。
パスを強制的に親テーマにした場合、子テーマでテンプレートの上書きができなくなるので注意してください。
固定ページの変更例
add_filter( 'template_include', function( $template ) {global $wp_query;$page = isset( $wp_query->query['pagename'] ) ? $wp_query->query['pagename'] : '';if ( '' === $page ) return $template;$new_template = '';switch ( $page ) {case 'sample' :case 'example' :case 'test' :$new_template = __DIR__ . '/templates/page/' . $page . '.php';break;}if ( '' !== $new_template && file_exists( $new_template ) ) {return $new_template;}return $template;} );
global $wp_query;$page = isset( $wp_query->query['pagename'] ) ? $wp_query->query['pagename'] : '';if ( '' === $page ) return $template;
まず、クエリを見て固定ページのリクエストかどうかを確認します。
そして固定ページであれば、ページスラッグを取得、なければデフォルトのテンプレートパスを返します。
$new_template = '';switch ( $page ) {case 'sample' :case 'example' :case 'test' :$new_template = __DIR__ . '/templates/page/' . $page . '.php';break;}
固定ページのスラッグが「sample」「example」「test」であれば、テーマ直下の「templates/page/sample.php」を指定するという内容になります。
パス等は使用環境に応じて調整が必要です。
if ( '' !== $new_template && file_exists( $new_template ) ) {return $new_template;}return $template;
新しいテンプレートファイルがあればそのファイルが存在するのかを確かめます。
存在していれば新しいテンプレートファイルパスを、なければ元のテンプレートファイルパスを返します。
これで、テーマ直下に「page-sample.php」というファイルがあったとしても「theme/templates/page/sample.php」が読み込まれるようになります。
まとめ
テンプレートのフック、その方法について理解できたのではないでしょうか。
テンプレート階層についてはいくらでも記事見つかると思いますが、テンプレートの変更についてはなかなか見つからないと思います。
凝った要望にこたえなければいけないテーマ作成者の参考になればと思います。