WordPressテーマTwenty Twenty-Threeの子テーマでテンプレートを判別する

運営しているブログに仍っては、カテゴリー毎にデザインを変えるなど屡々発生する要請です。WordPressには当該ページのカテゴリーを判別する組み込み関数が用意されています。一つは当該ページが、カテゴリーページか否かを返す「is_category()」、もう一つは当該ページが任意カテゴリーか否かを返す“in_category()”で、共にBool関数で引数の真偽を判定して“true”若しくは“false”を返す条件判定関数です。此れに仍ってカテゴリーページの場合であれば条件を調整しながら、任意のコードや任意のスタイルシートを任意のカテゴリーに限定して追加出来ます。

上は投稿ページでの機能になりますが、同様にWordPressでは固定ページ毎にテンプレートを指定出来ます。固定ページでは固定ページ同士の親子関係も指定可能ですから、任意のページの下層に置かれた固定ページの全てに同じデザインを当て嵌めたい要請も屡々です。テンプレート自体は固定ページの投稿画面で指定可能ですが、此の時同じデザインを適用したい固定ページに同じテンプレートを指定すれば良いでしょう。此れを判定する機能を持つ組み込み関数が“is_page_template()”でした。

is_page_template()

組み込み関数“is_page_template()”はソースの“/wp-includes/post-template.php”を見れば、WordPressのバージョンが2.5.0からのもので、現行バージョンが6.3であれば可成り古い部類に属するのではないでしょうか。此れを引数を持たせずに用いればテンプレートが利用されているページが如何か、即ち固定ページの投稿画面でテンプレートを指定したが如何かの真偽が判定されますが、引数を持たせれば其れに該当するテンプレートであるか如何かの真偽が返り、従って特定のテンプレートが使用されているか如何かの判定に使えると言う按配の組み込み関数です。

引数には使われているか如何かを調べたいテンプレートに関する文字列を持たせるのでしたが、利用した向きには少しく奇異に感じた経験があれば同意せざるを得ません。構文を端的に言えば、以下の如く文字列として“パス”を与えるのです。

スポンサーリンク
is_page_template( 'hoge/fuga.php' )

関してテーマディレクトリを起点とすれば、子テーマに“hoge”フォルダが設けられていて、“fuga.php”ファイルが用意されているのがテンプレートファイルであり、此れを固定ページの投稿画面で指定していれば“真”と判定される勘定です。先ず先ず此の手の関数に於いては大凡は“スラッグ”を与えるのでしたが、スラッグには通常“ピリオド”や“スラッシュ”の様な正規表現に特別な意味を保有する文字は使用されませんが、此れがテーマディレクトリ直下にテンプレートファイルが置かれていてさえ“.php”なる“拡張子”を伴った文字列を引数に与えるのは些か違和感が有ったのでした。

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

処で、WordPressを利用して新規にwebサイトを構築する際には、最新のデフォルトテーマを選択し、此の子テーマを作成してデザインや任意の機能を此の中で適用して行くのが通常となっています。子テーマにするのは親テーマたる最新のデフォルトテーマがバージョンアップ時に施した処理データを失わない為ですが、最新のデフォルトテーマを選択して親テーマとするのはWordPressを利用するに当たり成る可くWordPressの作法に従いたい要請が有るからです。屡々此の要請を無視した独善的なテーマに行き当たりはしますが、サイト構築を請け負っては此れを繰り返している内にいつしか古くなった独善的テーマは問題を多く抱えるからで、此の尻拭いに追われるのも珍しく有りません。最新のデフォルトテーマにはWordPress開発チームの目論見や方針が見える事情も相俟っては、出来る限り此れを親テーマとして利用すべきです。

プログラムに指定された利用するファイル及びプログラムを、親テーマを探す前に子テーマ内を探す構造になっておれば、勢い子テーマに於いては親テーマのディレクトリ構造を考え、元にした上で其のディレクトリ構造は構築されねばなりません。

扨、従来はデフォルトテーマ内に特定のテンプレートディレクトリは用意されていませんでした。辛うじて其のよすがが感じられたのが“template-parts”フォルダでした。此のフォルダは“Twenty Sixteen”テーマから見え始めていますが、但し文字通りテンプレートのパーツを収めるフォルダにて基本的には以下の如き構文で読み込まれるテンプレートの部品のファイルを収めておくフォルダです。

<?php get_template_part( 'template-parts/breadcrumbs' ); ?>

上記の例で言えば“パンくずリスト”部品を“template-parts”フォルダから読み出して使用するのであり、他に部品の例を挙げれば例えば“Twenty Twenty”テーマでは一覧として以下が列挙されます。

  • content-cover.php
  • content.php
  • entry-author-bio.php
  • entry-header.php
  • featured-image.php
  • footer-menus-widgets.php
  • modal-menu.php
  • modal-search.php
  • navigation.php
  • pagination.php

此れ等部品を読み込む側として想定されているのがテンプレートファイルであり、例えば“Twenty Sixteen”テーマで言えば、テーマディレクトリ直下に以下が見られます。

  • index.php
  • page.php
  • search.php
  • single.php
  • 404.php
  • archive.php

此れ等ファイルはテーマディレクトリ直下に“functions.php”ファイルや“style.css”、及びテンプレートファイルとも呼び得る “comments.php”、 “footer.php”、 “header.php”、 “image.php”、 “searchform.php”、 “sidebar-content-bottom.php”、 “sidebar.php”、 などと共に渾然一体として配置されていたのであり、WordPress開発チームと言えど此れを整理したくなるのが人情と言うものかと思います。

新設された“templates”フォルダ

上記が如き状況は“Twenty Twenty-One”テーマ迄は相変わらず、テーマディレクトリ直下には“template-parts”フォルダが見えましたが、当該状況が変じたのは“Twenty Twenty-Two”テーマでした。

バージョン5.9で導入されたフルサイト編集機能と其れを活かすべく登場したテーマ「Twenty Twenty-Two」を以て明らかとなったのです。

本ブログ2022年2月26日の記事[※1]に上記の如く記した通り、愈々本格的にブロックエディター化に邁進し始めたWordPressに於いてはデフォルトテーマも最適化されたのですが、其のテーマたる“Twenty Twenty-Two”テーマの直下には“templates”フォルダが用意されていたのです。そしてフォルダ内に用意されるファイルの拡張子は、以下列挙する如く“.php”ではなく“.html”でした。

  • 404.html
  • archive.html
  • blank.html
  • home.html
  • index.html
  • page-large-header.html
  • page-no-separators.html
  • page.html
  • search.html
  • single-no-separators.html
  • single.html

ファイル名自体は“Twenty Sixteen”テーマを踏襲しているのが明白ですから、フォルダ名と併せ、テンプレートとして機能するファイル群であるのは間違いありませんが、少しく驚かされた向きも多かったのでは無いでしょうか。そして其れは新デフォルトテーマ“Twenty Twenty-Three”でも勿論踏襲されています。以下列挙の通りです。

  • 404.html
  • archive.html
  • blank.html
  • blog-alternative.html
  • home.html
  • index.html
  • page.html
  • search.html
  • single.html

実は“Twenty Twenty”テーマの直下には“templates”フォルダが用意されていましたが、“Twenty Twenty-One”テーマの直下からは失われており、“Twenty Twenty-Two”テーマに至って復活した形になっています。“Twenty Twenty”テーマには“Twenty Sixteen”テーマ以来の“templates-parts”フォルダも並列して存在しており、加えて“templates”フォルダ内には“template-cover.php”、“template-full-width.php”と二つの“PHP”ファイルが用意されるのみですから“Twenty Twenty-Two”テーマ以降の“templates”フォルダとは些か意味合いが異なり、多少行きつ戻りつして“templates”フォルダは今其の役割を明確にされたものと考えられます。

独自に新規テンプレートファイルを追加する

以上の状況を鑑みれば、独自にテンプレートファイルを追加する方法は容易に推測可能です。ファイル名を任意のもの、拡張子を“.html”として新規ファイルを作成し、子テーマにもディレクトリ直下に“templates”フォルダを作成し、其の中に放り込めば宜しいでしょう。果たして、新規固定ページを作成し、テンプレートを適合するに於いては、例えば“templates/piyo.html”を用意しておけば、プロパティのプルダウンメニューに「piyo」が現れます。

蛇足ですが、独自にテンプレートファイルを追加するに当たってはプレーンなHTMLファイルでも構わない様ですが、しかしWordPressに於いてはヘッダー、フッター、コンテンツを読み込むのは作法ですので、此れを実現したくば親テーマ“Twenty Twenty-Three”の“templates”フォルダ内に用意される一つ“templates/page.html”でも複製して適宜改訂し、子テーマの“templates/piyo.html”へリネームして放り込めば宜しいでしょう。因みに“templates/page.html”ファイルの内容は以下となっており、WordPressの作法に従ったテンプレート構文が記されているのが見て取れます。

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","style":{"spacing":{"margin":{"top":"var:preset|spacing|50"}}}} -->
<main class="wp-block-group" style="margin-top:var(--wp--preset--spacing--50)">
	<!-- wp:group {"layout":{"type":"constrained"}} -->
	<div class="wp-block-group">
		<!-- wp:post-featured-image {"overlayColor":"contrast","dimRatio":50,"align":"wide","style":{"spacing":{"margin":{"bottom":"var:preset|spacing|50","top":"calc(-1 * var(--wp--preset--spacing--50))"}}}} /-->
		<!-- wp:post-title {"level":1,"style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}}} /-->
	</div>
	<!-- /wp:group -->

	<!-- wp:post-content {"layout":{"type":"constrained"}} /-->
	<!-- wp:template-part {"slug":"comments","tagName":"section"} /-->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

テンプレートを判別する

扨、本記事の本題です。例えば此の“piyo”テンプレートが利用されているページに於いてのみ、任意のスタイルシートを宛行いたい要請が有ります。従来であれば此れは上記を援用して以下で判定可能となり真偽が返る筈でした。

is_page_template( 'templates/piyo.html' )

しかし此れは上手く機能しませんので、恐らくは“Twenty Twenty-Two”テーマからは些か理屈が変わったのだろうと推測し、上述した“wp-includes/post-template.php”ファイルに定義される“is_page_template”関数のソースを見てみれば以下となっています。

function is_page_template( $template = '' ) {
	if ( ! is_singular() ) {
		return false;
	}

	$page_template = get_page_template_slug( get_queried_object_id() );

	if ( empty( $template ) ) {
		return (bool) $page_template;
	}

	if ( $template == $page_template ) {
		return true;
	}

	if ( is_array( $template ) ) {
		if ( ( in_array( 'default', $template, true ) && ! $page_template )
			|| in_array( $page_template, $template, true )
		) {
			return true;
		}
	}

	return ( 'default' === $template && ! $page_template );
}

“get_page_template_slug”関数を用いて引数と照合して真偽を返しているのが分かります。其処で同ファイル中に“get_page_template_slug”関数のソースを見ればバージョン3.4.0から実装された関数は以下となっています。

function get_page_template_slug( $post = null ) {
	$post = get_post( $post );

	if ( ! $post ) {
		return false;
	}

	$template = get_post_meta( $post->ID, '_wp_page_template', true );

	if ( ! $template || 'default' === $template ) {
		return '';
	}

	return $template;
}

“get_post_meta”関数に仍りテンプレートを求めていますが、此れはお馴染みカスタムフィールドのデータを取得する関数ですので、第二引数となるキー文字列“_wp_page_template”に対応すカスタムフィールドデータが得られますが、これこそが固定ページのプロパティとしてプルダウンメニューから与えた文字列でした。すると“is_page_template”関数に与える引数はパスならずして、例えばテンプレート名「piyo」が求められるべきで、其の通り、以下の如く与えてみれば、当該固定ページに於いて確りと“is_page_template”関数は真値を返すのでした。

is_page_template( 'piyo' )

パスを引数に取る違和感よりは遥かにスッキリした感じがして、WordPress開発陣の求める所だろうと感じます。

テンプレート名

テンプレート名を引数に与えると言う、スマートな処理でテンプレート判別が可能となるのでしたが、しかし上の「独自に新規テンプレートファイルを追加する」段での処理に於いては特にテンプレート名を与えていません。此れは独自テンプレートファイルの子テーマの“templates/piyo.html”の元ファイルの親テーマの“templates/page.html”でも事情は同じです。何としてもWordPressシステムが勝手にテーマフォルダ内からテンプレート名を抽出していると考えなければなりません。此処に来てテーマフォルダ直下に新設された“templates”フォルダも意味を持って来る筈です。

関してはWordPressシステムに指定した任意のスラッグに対応するブロックテンプレートファイルをテーマから取得する関数が用意されている筈ですが、其れは“wp-includes/block-template-utils.php”ファイルにプライベートな関数として定義されていました。“_get_block_template_file()”関数です。WordPressのバージョン5.9.0から実装されたもので正しく「新設された“templates”フォルダ」の段に記した様に“Twenty Twenty-Two”テーマと同時に登場したのでした。以下にソースを記します。

function _get_block_template_file( $template_type, $slug ) {
	if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) {
		return null;
	}

	$themes = array(
		get_stylesheet() => get_stylesheet_directory(),
		get_template()   => get_template_directory(),
	);
	foreach ( $themes as $theme_slug => $theme_dir ) {
		$template_base_paths = get_block_theme_folders( $theme_slug );
		$file_path           = $theme_dir . '/' . $template_base_paths[ $template_type ] . '/' . $slug . '.html';
		if ( file_exists( $file_path ) ) {
			$new_template_item = array(
				'slug'  => $slug,
				'path'  => $file_path,
				'theme' => $theme_slug,
				'type'  => $template_type,
			);

			if ( 'wp_template_part' === $template_type ) {
				return _add_block_template_part_area_info( $new_template_item );
			}

			if ( 'wp_template' === $template_type ) {
				return _add_block_template_info( $new_template_item );
			}

			return $new_template_item;
		}
	}

	return null;
}

以てWordPressシステムは特にファイルにテンプレート名を記述しなくとも固定ページのテンプレートプルダウンメニューによしなにテンプレート名を列挙するのでしたが、此処にテーマディレクトリとテンプレート名たる“スラッグ”を繋ぐ文字列を取得す関数として“get_block_theme_folders”が用意されているのが見て取れます。此の関数もバージョン5.9.0から実装され、其のソースは以下となっています。

function get_block_theme_folders( $theme_stylesheet = null ) {
	$theme_name = null === $theme_stylesheet ? get_stylesheet() : $theme_stylesheet;
	$root_dir   = get_theme_root( $theme_name );
	$theme_dir  = "$root_dir/$theme_name";

	if ( file_exists( $theme_dir . '/block-templates' ) || file_exists( $theme_dir . '/block-template-parts' ) ) {
		return array(
			'wp_template'      => 'block-templates',
			'wp_template_part' => 'block-template-parts',
		);
	}

	return array(
		'wp_template'      => 'templates',
		'wp_template_part' => 'parts',
	);
}

テーマディレクトリ直下に“block-templates”フォルダ若しくは“block-template-parts”フォルダが用意されていなければ、デフォルト値として['wp_template' => 'templates', 'wp_template_part' => 'parts']の連想配列が返り、此処に“is_page_template()”関数は、新設された“template”内から、与えた引数と文字列を同じくする拡張子を除去した任意のスラッグ名が存在するか如何かを判定する仕儀と相成るのでした。

因みに連想配列のもう一つの要素として返る“parts”に於いては、“Twenty Twenty-Two”テーマにも“Twenty Twenty-Three”テーマにも当該名のフォルダが用意されており、其の中には上の「テンプレートディレクトリ」の段にも「テンプレートファイルとも呼び得る」と記した処の “footer.php”、 “header.php”などの一連のファイルが用意される役処となっており、 “テンプレート”と、主として其れ等の一連のファイルの中で横断的に用いられる “パーツ”との役割分担が従来より明確になったものと捉えられます。

扨、従来はパスを含んだファイル名で識別されていたテンプレートは、一つ前のデフォルトテーマ“Twenty Twenty-Two”及び、最新のデフォルトテーマ“Twenty Twenty-Three”では特定のフォルダ、基本的には“template”フォルダに“HTML”ファイルとして収める必要があり、最初から両デフォルトテーマに用意されているテンプレートファイルは上述した様に勿論此の規則に従っており、子テーマでも同規則に従えば独自のテンプレートとして当然ながら利用可能となるのでした。

従って本記事に、“Twenty Twenty-Two”テーマ若しくは“Twenty Twenty-Three”テーマを親テーマとして採用した場合、其の子テーマに於いて独自のテンプレートファイルを用いる場合には、子テーマディレクトリ直下に“template”フォルダに“HTML”ファイルを用意し、此のファイル名から拡張子を除いた文字列はテンプレート名として機能して、“is_page_template()”関数の引数として与えれば当該テンプレートか否かの真偽値が返る、なる結論が齎されました。

WordPressに関するGoogle検索について

本邦に於いては最早Googleを検索エンジンとして用いるのが当たり前となっていますし、検索エンジンを利用して情報を集めるのは記事をものする常ですが、しかし、Google検索エンジンの結果出力の劣化が言われて久しくある中で、当該事象は本記事執筆時にも深く感じられる所でした。本記事、更に言えば関しては一つ前の記事[※2]も併せて、検索結果に望む情報が得られず実に難儀しました。

本記事を通読された向きならご理解くださるでしょう、此方としては例えばWordPressの関数についての機能や解説、用例やソースの在り処、などを知りたく検索しているのですが、吐き出される検索結果は凡そWordPressの初心者がWordPressの初心者に解説を試みた様な風変わりな頁ばかりで、全く役に立つものが無く困り果ててしまいました。仕方なくローカルにWordPressのソースを用意して検索を掛けたり、GitHubに於いて検索を掛けたりして漸々最低限の情報を掻き集めて本記事を書き上げられましたが、実はもう一つ役に立った情報源にはBingチャットが有りました。

AIの検索エンジンへの援用が此処の処喧しく言われていますが、此れを実感した印象です。Microsoft社は実に上手く検索エンジンにAI機能を組み込んでいる様に思えました。実はGoogle検索の結果に閉口しながら、此れからは本記事の様な情報を扱うには情報収集の難儀が懸念され、仕方なくも駄目元でBingチャットを利用してみたのですが、思わぬ好結果に、プログラミング関係の記事をものするには向後は更に利用の頻度が増えるものと考えています。

Google検索は世界を制覇し、其れは今も変わりませんが、考えてみればGoogle検索に命題の真偽を判定する能力は皆無で、出力結果は所詮は単なる人気投票にてGoogleがポピュリズムの権化たる所以ですし、又、真贋判定能力の無い、物の価値を判断出来ない者は勢い肩書やお墨付きを殊の外信用する他なく、其の儘詐欺に掛かっている様な印象さえGoogleからは窺えます。此の状況は如何に微に入り細を穿ってチューニングを施そうが、根本的な改善は無い筈ですし、又、近年にては碌でもない情報の検索結果順位を上げんと企むSEO屋の圧力に抗し切れずして、チューニング自体奇怪しな方向に走り迷走した挙句、奇怪な所謂“役に立つ”などと言う意味の無い修飾のされた検索結果が吐き出されるようになってしまっているようにさえ感じられます。余りにGoogleの検索結果が偏れば、其れは自身にも困る事態でもあり、願わくば根本的改善が施される様期待したく思います。

関連記事

  1. WordPressでTwenty Twenty-Twoを親テーマにした時に独自ブロックパターンを子テーマに追加する(Acenumber Technical Issues:2022年2月26日)
  2. WordPressテーマTwenty Twenty-Threeの子テーマにグローバルカスタムメニューを追加する(Acenumber Technical Issues:2023年5月5日)