【WordPress】別ディレクトリに保管しているカスタム投稿テンプレートを呼び出す

ワードプレスにいろんなページを追加していると、テーマディレクトリ内にsingle-{post_type}.phpとかpage-{post_type}.phpとか、archive-{post_type}.phpとか。

投稿表示のカスタマイズ用ファイルがどんどん増えていきます。

フロント表示に必要かどうか選別しながらやっているつもりだったんですが。

機能やカスタム投稿の追加ごとに増やしてしまったため、ちょっと収集が付きそうにないなとw

どうやって整理するか

整理するとすれば機能をディレクトリごとに分けるのが一番です。

しかし、ワードプレスのテンプレート階層の縛りにより。

テーマディレクトリ以下のディレクトリではテンプレートをそのまま読み込む事はできません。

でも公開されているテーマを見ると、single.phpは一枚なのにいろんな投稿タイプをフォローしていたり。

そもそもプラグインは、プラグインのインストール時に生成されるディレクトリ内で、表示に使用するテンプレートファイルが含まれているわけです。

であれば、ディレクトリから読み込む方法はありそうなもんだなと。

そうすれば、機能毎のディレクトリ管理ができるようになります。

get_template_part()を条件分岐で使う

まず最初に思いついたのは、ワードプレスの初期テーマのsingle.phpなどで見かける関数get_template_part()を利用することです。

テーマディレクトリにはsingle.phpやpage.phpが用意されていて、その中身となるコンテンツを呼び出すことのできる関数です。

初期テーマですと、別ディレクトリ(templateという名前の事が多い印象です。)の中で、content-single.phpやcontent-page.phpといったPHPファイルを呼び出してますかね。

この場合、例えばsingle.php内のbody部にこんな感じで書かれます。

//templateディレクトリにあるコンテンツの中身を表示するcontent-single.phpを呼び出す
get_template_part( '/template/content', 'single' );

これで、投稿ページを表示する場合はcontent-single.phpが利用されるのです。

single.phpは個別投稿ページを表示する際に使用されるテンプレートファイルなので、この中で投稿タイプごとの条件分岐を入れれば、中身となるコンテンツのファイルは別ディレクトリで管理できるわけです。

//投稿タイプを取得
$post_type = get_post_type( $post_id );

if( $post_type == "test1" ){
  //カスタム投稿タイプtest1の時に使用するテンプレートファイルを指定
  get_template_part( 'test1/store', 'meal' );

elseif( $post_type == "test2" ){
  //カスタム投稿タイプtest2の時に使用するテンプレートファイルを指定
  get_template_part( 'test2/book', 'cook' );

} else{
  //それ以外の投稿タイプの時は初期値の表示
  get_template_part( 'content', 'single' );

}

最初の分岐では、カスタム投稿タイプ”test1”の時にtest1ディレクトリ内にあるstore-meal.phpを呼び出して表示させます。

2つ目の分岐もカスタム投稿タイプが”test2”の時にtest2ディレクトリ内にあるbook-cook.phpを呼び出します。

それ以外のときは、通常の表示であるcontent-single.phpを呼び出します。

こうすれば、テーマディレクトリ内に存在する個別投稿用のテンプレートはsingle.phpのみで、中身をディレクトリ管理できるようになるわけです。

悪くは無いですが、single.php自体に変更を加えたい状況になった場合に、single-{post_type}.phpを追加することになります。

制作を進めるうちにありえることなので、できれば作成したディレクトリ内で完結させたいところです。

・・・計画が甘いというのは置いといてください・・・

テンプレートを指定するフィルターフックがある

で、じゃあどうするかと調べたのが、最初に書いたようなプラグインのように用意したディレクトリからテンプレートを読ませる方法です。

で、どうやらフィルターフックの中にそれができるものがあるみたいで、表示に関わるほとんどのものに対応してるみたいですね。

上記リンクのリファレンスのユーザーメモを見ると、プラグイン内での利用が主みたいです。

今回の自分の場合は子テーマなので、ここから色々と調べて。

期待どおりの動作になったコードがこちらでした。

function single_otherdir_template( $template ){
    if( is_singular( 'test1' )  ){
        $template = get_stylesheet_directory() . '/test1/single-test1.php';
    }
    return $template;
}
add_filter( 'single_template', 'single_otherdir_template', 10, 1 );

is_singlular()で表示する投稿タイプが”test1”かどうかを判定し、真であれば’/test1/single-test1.php’からテンプレートファイルを返します。

$templateに入れるテンプレートファイルのありかを指定するのは絶対パスとのことなので、今回は子テーマで使えるget_stylesheet_directory()を利用しました。

あとは、個別投稿のテンプレートであるフィルターフック’single_template’で関数を実行すればOKです。

これをfunctions.phpに書けば完了ですが。

個人的にそれはディレクトリ管理でほぼ完結させることに反すると(勝手に)考え、このテンプレートで使用する関数を集めたPHPファイルを用意し、functions.phpはコメントとrequire_onceで済ませたりw

これでディレクトリで作成するもの以外は、ほぼ開かなくて済むのではないかとw

手間は減らせますね

少し前までは、テーマディレクトリと機能を集めたディレクトリを行ったり来たりしてたんですが。

さすがにファイルが増えすぎてうんざりしてました。

なかなかテンプレートのフックでうまく動作させることができなくて、get_template_part()で妥協しようかとも思いましたが。

ディレクトリの行き来を最低限にしたいと思い、あれこれ試したらできました。

意外とsingle.phpやpage.phpをいじることも多いので、考えている機能専用のテンプレートなので気兼ねも無いです。

これで作成する機能で使うものだけに集中できるので、だいぶ手間が減るなぁと思っている次第です。

参考:ワードプレスで子テーマを作らずに、カスタム投稿の投稿ページ用のテンプレートをプラグインで適用する方法‐サポトピア

参考:テーマ・親テーマおよび子テーマのディレクトリのURL、またはパスを取得する‐THE WORDPRESS PRESS