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

この記事は、不定期連載「できる!Snow Monkey カスタマイズ 」の第2回目です。

今回の記事のテーマ

前回の記事「できる!Snow Monkey カスタマイズ – 準備・基礎・初歩編」で行なったsnow_monkey_get_template_part_<name>フックでは、テーマに存在していたテンプレートパーツを置換する事を行いました。

しかし、テーマに存在しないテンプレートパーツを追加するなどはどうすれば良いでしょうか?

テンプレートのルートディレクトリを解説

今回の記事では、テンプレートのルートディレクトリについて知っていきましょう。

今回紹介するテンプレートのルートディレクトリについて知る事で、テーマに存在しないテンプレートパーツを追加して読み込むなどが可能になっていきます。

プラグインにテンプレートパーツを追加しよう

オリジナルのテンプレートパーツを追加する方法を解説します。

テンプレートのルートディレクトリって?

前回の記事「できる!Snow Monkey カスタマイズ – 準備・基礎・初歩編」では、デバッグモードで読み込むテンプレートパーツをコメントアウトで表示するようにしました。

デバッグモードで、ページを表示してみると

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

と言った記述などが書かれているのを確認できると思います。

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

ルートディレクトリroot directory

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

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

と、デジタル言葉辞典では書かれています。

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

テネーブル

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

テネーブル(アイコン01)

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

何が問題になるのか考えてみよう

プラグインでテンプレートパーツを扱いたい場合、読み込みには\Framework\Helper::get_template_part( テンプレートパーツ<slug>-<name>, 渡したい情報配列 );の関数を使用していました。
しかし、この関数の第1引数に指定されているのはテンプレートパーツ<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フックの説明を読むと、実はこのフックはv5.3.1で非推奨になってるんだ。代わりにsnow_monkey_template_part_root_hierarchyと言うフックが用意されたので、そっちを使うようにしよう!

ルミェール(アイコン01)

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がそちらを読み込むようになっているからです。

テネーブル(アイコン03)

確認が済みましたら、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>, 渡したい情報配列 );の関数などが実行された時にこのフックが実行されるみたい。
引数の感じも凄く似てるよね。

ルミェール(アイコン05)
テネーブル

ほとんどの場合は第2引数などは使われないかもしれませんが、第2引数の値などを条件にする事で、条件の時だけテンプレートを読み込むルートディレクトリを切り替える事が可能と言う事ですね!

テネーブル(アイコン05)

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_hierarchyフックは、配列でルートパスを複数持てるような仕様になっており、Snow Monkey v5.3.1から追加されています。

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

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

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

テネーブル

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

テネーブル(アイコン01)
ルミェール

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

ルミェール(アイコン01)

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

テネーブル

テンプレートパーツファイルを使わない条件の時には、空の配列を返却させる方が良いかもしれません。順にチェックしていくファイルチェック処理を行わなくする事で高速化が出来ます。

テネーブル(アイコン01)

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

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

テンプレートのルートディレクトリを設定し、その中にcustomize/test.phpなどと言ったファイルを配置するだけです。
この追加したテンプレートパーツの呼び出し処理は、

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

と言ったようになります。
テンプレートパーツの読込み処理で読込みをする事でcustomize/test.phpも通常のテンプレートパーツとして使用が可能となります。
ですから、snow_monkey_get_template_part_argsフックやsnow_monkey_get_template_part_<slug>-<name>フックと言ったテンプレートパーツを処理するフックも実行されます。

ルミェール

カスタマイズで追加するHTML領域をテンプレートパーツにすると、その領域もフックでカスタマイズ出来ちゃう。
php内にHTMLを記述する従来のやり方より、凄く便利に扱えるよ!

ルミェール(アイコン03)

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

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

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

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

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

page-templates(新規生成)

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

テネーブル

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

テネーブル(アイコン01)

最後に

今回の記事で紹介したテンプレートのルートディレクトリを知った事で、テーマにオリジナルのHTML領域を追加しやすくなったのではないでしょうか?

また追加したオリジナルのHTML領域もフックで、更にカスタマイズしやすくなったのではないでしょうか?

これまでの記事で実践した事を上手く応用して制作を行えば、オリジナルのHTML領域を追加するだけではなく、削除したいHTML記述を削除し、代わりに表示したいHTML領域をオリジナルのテンプレートで読み込んだ形で置換と言った事も可能でしょう。
是非、そう言った応用カスタマイズにも挑戦してみてください。

テネーブル

この記事に関するご相談やご質問などは、Not Wizの制作チームにお問い合わせください。

回答できる範囲で回答させていただきます。

また、テーマカスタマイズ方法の資料に使いたいなどの引用なども、ご自由にどうぞ。

(Snow Monkey公式に迷惑にならない配慮だけ、お願い致します)

テネーブル(アイコン01)