テンプレートのルートディレクトリの基礎 – Snow Monkey カスタマイズ

本記事は、「テンプレートのルートディレクトリ」について解説しています。

最初に

Snow Monkey の snow_monkey_template_part_render フックでは、テーマに存在しているテンプレートパーツの表示を置換することが可能です。しかし、テーマに存在していないテンプレートパーツを追加するのは、プラグインで行う場合はどのようにすれば良いのでしょうか?
それは、「テンプレートのルートディレクトリ」を使うことで解決します。

テンプレートのルートディレクトリとは

デバッグモードで、ページを表示してみましょう。

補足説明

デバッグモードで読み込むテンプレートパーツをコメントアウトで表示する方法については、「Snow Monkey カスタマイズをはじめよう – 準備編」の記事で解説しています。

<!-- Start : template-parts/nav/drawer -->

と言った記述などが、デベロッパーツール や Webインスペクタ内で記述されているのを確認可能です。

テネーブル

確認できたところで、「ルートディレクトリ」の言葉について調べてみましょう。

ルートディレクトリroot directory

ファイル構造システムにおいて、階層における最上位ディレクトリ

デジタル言葉辞典より引用

と、デジタル言葉辞典には記載されています。

先ほど確認した template-parts/nav/drawer と言うテンプレートパーツのファイルは Snow Monkey のテーマディレクトリ/template-parts/nav/drawer.php ファイルでした。では、この場合のルートディレクトリは、どうなるでしょうか?

テネーブル

この場合のケースであれば、template-parts/nav/drawer と書かれている元のディレクトリが、ルートディレクトリに該当します。なので、この場合「テンプレートのルートディレクトリ」とは、その最上位のディレクトリである Snow Monkeyのテーマディレクトリ となります。

プラグインにテンプレートパーツファイルを追加してみよう

何が問題になるのか、考えてみましょう

プラグインでテンプレートパーツを扱いたい場合、読み込みには\Framework\Helper::get_template_part( テンプレートパーツの<slug>-<name>, 渡したい情報配列 ); の形で \Framework\Helper::get_template_part 関数を使用していました。
しかし、この関数の第1引数に指定されているのは テンプレートパーツの<slug>-<name> です。
テンプレートのルートディレクトリなどの指定はありません。指定した テンプレートパーツの<slug>-<name>Snow Monkeyのテーマディレクトリ 内のテンプレートパーツを読んでいます。なので、このままではSnow Monkey のテーマディレクトリ内のテンプレートパーツしか読まれません。どうすれば、プラグイン内のテンプレートパーツを読み込めるのでしょうか?

プラグイン内のディレクトリもテンプレートのルートディレクトリに設定できれば、問題を解決できそうです。

テンプレートのルートディレクトリを設定しよう

問題解決のステップとして、まずは Snow Monkey でそのような機能があるかフックの定義を探すことから始めましょう。

Snow Monkey フック一覧 – snow_monkey_template_part_root

Snow Monkey のフック一覧を確認してみると Filter Hooksnow_monkey_template_part_root フックが該当しそうなことが解るでしょう。

テネーブル

しかし、snow_monkey_template_part_root フックの説明を読めば、このフックは Snow Monkey v5.3.1 で非推奨になっていることも解ります。代わりに snow_monkey_template_part_root_hierarchy と言うフックが用意されていることも記載されていることが解ります。そちらを使うようにしましょう。

snow_monkey_template_part_root_hierarchy フックを使う

試しに「My Snow Monkey プラグイン」にフック処理を書いてみましょう。my-snow-monkey.php に次の記述を追加しましょう。

add_filter(
	'snow_monkey_template_part_root_hierarchy',
	function( $hierarchy, $slug, $name, $vars ) {
		// 渡されてきた $hierarchy に、プラグインディレクトリ内の template_root を追加する
		$hierarchy[] = untrailingslashit( __DIR__ ) . '/template_root';
		return $hierarchy;
	},
	10,
	4
);

上記のコードを追加し、プラグインのディレクトリに template_root の名前でディレクトリを新規生成します。

plugins(プラグインディレクトリ)

my-snow-monkey

my-snow-monkey.php

template_root(新規生成)

template-parts(新規生成)

nav(テスト用に新規生成)

global.php(テスト用に新規生成)

この template_root ディレクトリが、プラグインのテンプレートルートのディレクトリになります。

この template_root ディレクトリに template-parts/nav/global.php ファイルを生成し、次のように記述します。

<?php
  echo 'test';

実際にページを開いて確認しましょう。

テネーブル

グローバルメニューの部分が test と言う文字列に変わっているのを確認できましたか?

追加したプラグイン内の template_rootテンプレートのルートディレクトリ として見るようになったので、グローバルメニューを表示する為にあるテンプレートパーツの template-parts/nav/global.php がそちらを読み込むようになっているからです。

確認が済みましたら template-parts/nav/global.php ファイルを削除して、元のグローバルメニューが表示されるようにしておきましょう。

snow_monkey_template_part_root_hierarchy フックの実行タイミング、引数と返却値について

snow_monkey_template_part_root_hierarchy フックは、テンプレートの読込み時に実行されるフックです。

  • 第1引数の $hierarchy は、テンプレートのルートディレクトリを値として持つ配列です。返却値にも使用されます。
  • 第2引数の $slug は、読み込まれたテンプレートの slug値 となります。
  • 第3引数の $name は、読み込まれたテンプレートの name値 となります。
  • 第4引数の $vars は、テンプレートの読込み時に渡される値になります。
ルミェール

\Framework\Helper::get_template_part( テンプレートパーツ<slug>-<name>, 渡したい情報配列 ); の処理などが実行された時に、このフックも実行されるみたい。引数の感じも凄く似てるよね。

テネーブル

ほとんどの場合は、第2引数などは使われないでしょう。しかし、第2引数の値などを条件にすることで、条件に該当された時だけテンプレートを読み込むルートディレクトリを切り替えるなどの条件判定を可能になっています。

snow_monkey_template_part_root_hierarchy フック、配列を返却するのは何故?

snow_monkey_template_part_root_hierarchy フックが、ルートディレクトリの配列を返却するのは何故でしょうか?ルートディレクトリは、1つでは駄目なのは何故なのかを解説します。

非推奨となった snow_monkey_template_part_root フックは、配列を返却しないフックであり、返却値は1つです。その為、基本的にルートディレクトリは設定した1つか、テーマディレクトリになってしまう問題がありました。その問題の結果としては、もし複数のプラグインで snow_monkey_template_part_root フックを使用した場合は、優先度の高い該当のフックの返却値がルートディレクトリに設定されてしまう問題がありました。もし、優先度が他のプラグインより低ければ、そのプラグインで設定したルートディレクトリは正しく参照されません。その為、意図しない動作で処理をされてしまうか、複数のプラグインで動作させた場合には処理エラーが発生してしまう問題がありました。

その問題を踏まえ、snow_monkey_template_part_root フックは非推奨となりました。 代わりに Snow Monkey v5.3.1 から snow_monkey_template_part_root_hierarchy フックが追加され、複数のルートパスを配列で設定できる仕様になっています。

テンプレート読み込みは、設定されたルートディレクトリ配列を次々に調べていきます

snow_monkey_template_part_root_hierarchy フックで return しているのは $hierarchy と言うディレクトリパスを値に持つ配列です。

各テンプレートパーツの読込み処理は、この $hierarchy に値が追加された順に、ディレクトリパス内のテンプレートパーツのファイルが存在するかチェックし、ファイルが存在する場合にはそのテンプレートパーツを使用する仕様になっています。存在しない場合の最後は、テーマディレクトリを調べます。それでもファイルが存在しない場合は、テンプレートパーツファイルの読込みは行われません。

テネーブル

追加された順に読み込むので、配列の並び順が先頭にあればあるほど優先的になります。

ルミェール

フックの優先度を低く設定しても array_unshift 関数などを使うと配列の先頭に追加可能なので、フックの優先度でルートディレクトリの読込み順が必ずしも決まる訳じゃないよ。そこは注意しよう!

また、テンプレートパーツファイルの読込みが行われない場合であっても snow_monkey_get_template_part_args フックや snow_monkey_get_template_part_<slug> フックと言ったテンプレートパーツを処理するフックを実行されます。それらのフック処理に何らかの出力を行う処理があった場合は、その処理結果を出力します。テンプレートパーツファイルを必ず存在させる必要はありません。

テネーブル

テンプレートパーツファイルを使わない条件の時に、snow_monkey_template_part_root_hierarchy フックを処理する場合は、空の配列をすぐに返却させるのが良いでしょう。順にチェックしていくファイルチェック処理を行わなくすれば、少しの高速化も可能です。

カスタマイズ用のテンプレートパーツを追加

さて、テンプレートのルートディレクトリについて理解が深まったところで、カスタマイズ用のテンプレートパーツを追加する場合も、どうすれば良いか見当がついたと思います。

テンプレートのルートディレクトリを設定し、その中に customize/test.php などと言ったファイルを配置するだけです。

この追加したテンプレートパーツの読込み処理は

ob_start();
\Framework\Helper::get_template_part( 'customize/test' );
$_html = ob_get_clean();

と言ったように get_template_part 関数を使用して、テンプレートパーツを読み込みます。

テンプレートパーツの読込みを get_template_part 関数で行うことで customize/test.php も通常のテンプレートパーツと同じように読込まれます。なので、snow_monkey_get_template_part_args フックや snow_monkey_get_template_part_<slug>-<name> フック、snow_monkey_template_part_render フックなども処理した時に実行されます。

ルミェール

独自のテンプレートパーツでもテンプレート系のフックが自動的に呼ばれるようになることで、標準のテンプレートパーツのようにカスタマイズしやすくなるんだ。従来の子テーマなどより、凄く便利に扱えるはず!

カスタムページテンプレートをプラグインで

本記事で解説した snow_monkey_template_part_root_hierarchy フックを使用することで、Snow Monkey v6 以降ではカスタムページテンプレートもプラグインで追加できるようになっています。

Snow Monkey公式Webサイト – 使い方「カスタムページテンプレートの追加方法」

上記の Snow Monkey 公式ウェブサイトの記事では子テーマで追加を行なっていますが、その「1. 子テーマを用意する」部分を行わず、その手順の代わりにテンプレートのルートディレクトリを snow_monkey_template_part_root_hierarchy フックを使用して設定してください。
2. カスタムページテンプレート用のディレクトリを作成する」からの手順も子テーマで追加などせず、次のようにプラグインのテンプレートルートディレクトリ内で同様に page-templates ディレクトリを新規生成します。

プラグインのテンプレートルートディレクトリ

page-templates(新規生成)

それ以降の手順は、同様に新規生成した page-templates ディレクトリ内でファイル作成などを行えば、プラグインでカスタムページテンプレートを作ることが可能になっています。

テネーブル

子テーマの style.css に記述するスタイルシートの手順に関しましては style.css に記述する代わりに、管理画面から [外観] > [カスタマイズ] メニューの [追加CSS] 設定を使用されるか、wp_enqueue_style フックなどを使用しプラグインから CSS を追加で読込む処理を行なって適用するようにしてください。

最後に

本記事で解説をしたテンプレートのルートディレクトリについて理解すれば、ウェブサイトにオリジナルのテンプレートを追加しやすくなります。別記事も参考にし、上手く応用して制作を行ってみてください。予想以上にウェブサイトのデザインを思い通りにカスタマイズできるでしょう。是非、挑戦してみてください。

この記事の筆者

Kmix39(ケミ)

電子の妖精。当ウェブサイトの記事制作などを行なっています。
金融・不動産・医療・教育などの数々の業種のシステム開発を経験を積み、スマートフォンアプリケーションと WordPress などのウェブアプリケーションを日々勉強中。