WordPressは子テーマを使用すると親テーマのバージョンアップの影響を受けることなくカスタマイズできます。
どんな仕組みで子テーマが動作しているのか調べてみました。
子テーマ選択時の動作
テーマの管理画面でテーマを選択すると、データベースのoptionsテーブルに次のレコードが追加、または更新されます。
| フィールド名 | |
|---|---|
| option_name | option_value |
| 'stylesheet' | style.cssがあるディレクトリ |
| 'template' | テンプレートディレクトリ |
option_valueフィールドには、選択したテーマのディレクトリ名がセットされます。
例えば /wp-content/themes/my-theme だとしたら、'my-theme' がセットされます。
現在のテーマが子テーマでないときは、'stylesheet'と'template'は同じ値になります。
しかし現在のテーマが子テーマのとき、つまりstyle.cssのヘッダに Template: が指定されているとき、Template: の値が'template'にセットされます。
- /*
- Theme Name: Twenty Fifteen Child
- Theme URI: http://example.com/twenty-fifteen-child/
- Description: Twenty Fifteen Child Theme
- Author: John Doe
- Author URI: http://example.com
- Template: twentyfifteen
- Version: 1.0.0
- License: GNU General Public License v2 or later
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
- Tags: light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
- Text Domain: twenty-fifteen-child
- */
実際には、「Theme Name:」「Template:」「Version:」の3つがあれば動作します。
(「Version:」はなくても動くかも?)
このとき、'twentyfifteen' が'template'にセットされるわけです。
親テーマと子テーマのディレクトリ特定
親テーマと子テーマのディレクトリパスは、定数TEMPLATEPATH および定数STYLESHEETPATH で取得できます。
このディレクトリは、フルパスです。
| 定数 | 内容 |
|---|---|
| TEMPLATEPATH | 親テーマのディレクトリ |
| STYLESHEETPATH | 子テーマのディレクトリ |
二つの定数が同じなら、現在のテーマが子テーマでないことが確認できます。
- if ( TEMPLATEPATH === STYLESHEETPATH ){
- // 現在のテーマが子テーマでないときの処理
- }
各定数は次のように定義されています。
- define( 'TEMPLATEPATH', get_template_directory() );
- define( 'STYLESHEETPATH', get_stylesheet_directory() );
get_template_directory() はoptionsテーブルから 'template' の値を、get_stylesheet_directory() は 'stylesheet' の値を取得して、'ホームディレクトリ/wp-content/themes/' の後に結合したものを返しています。
なお、二つの定数はプラグインが実行された後にセットされます。
ほとんどないと思いますが、もしプラグインでテーマのパスを使用するなら、定数は使用できません。
上の関数を呼び出しましょう。
function.phpの実行順番
親テーマと子テーマの両方ともfunction.phpがある場合、子テーマ → 親テーマの順番で実行されます。
そのため同名の関数をfunction.phpに定義するとエラーになります。
親テーマの関数を子テーマで上書きするような使い方はできないので、注意が必要ですね。
フィルターやアクションは優先度が同じ場合、追加した順番で実行されます。
つまり同じ形式でadd_filter()またはadd_action()を実行すると、子テーマから実行されるのです。
翻訳データを親テーマと子テーマで個々に用意していて同じテキストドメインで翻訳データの読み込みをした場合は、二つの翻訳データは結合されます。
ただし、同じキーワードが存在する場合は、先に読み込んだ方が残ります。
アクションの優先度指定などをしない限り、タイミングとしては子テーマの読み込みが速いので、子テーマの翻訳が優先されますね。
翻訳データの読み込みについては、次の記事を読んでみてください。
WordPress: load_theme_textdomain()とload_plugin_textdomain()関数を少し詳しく解説してみる
テンプレートの選択
index.php や single.php などのテンプレートファイルは、次の順番でファイルが存在しているかチェックされます。
- 定数STYLESHEETPATH 内にあるか(子テーマディレクトリ)
- 定数TEMPLATEPATH内にあるか(親テーマディレクトリ)
- /wp-include/theme-compat/ 内にあるか
ファイルの存在が確認されると、そのファイルを読み込みます。
以降の存在チェックはおこないません。
現在のテーマが子テーマでない場合でも、①と②は実行されます。つまり同じファイルを2回チェックします。
記憶媒体へのアクセスは重い処理なので、少し無駄な気がしますね。
実際にはファイルの存在確認した結果をPHPがキャッシュしているので、速度的な問題はありません。
個人的にはキャッシュに頼るな、と言いたいですが。。。
③/wp-include/theme-compat/ には、次のファイルが格納されています。
comments.php
embed.php
embed-404.php
embed-content.php
footer.php
footer-embed.php
header.php
header-embed.php
sidebar.php
ヘッダーやフッターはデフォルトが用意されているようですね。
これ以外のテンプレートファイルは、例えばarchive.phpとかcategory.phpなどが存在しないとき、最終的にテーマディレクトリの index.php が選択されます。
ページタイプ毎のテンプレート選択については、次の記事を読んでみてください。
function.phpやテンプレート以外の子テーマ適用
function.phpやテンプレート以外は、子テーマで同名ファイルを用意しても切り替えてくれません。
あまり需要がないんでしょうね・・・
無理やり場面を想定してみます。
Webページにヘッダー画像が表示されているとします。
このヘッダー画像は、テーマディレクトリの直下にあります。
子テーマに同名の画像ファイルがあるときは、ヘッダー画像をそちらに切り替えます。
/wp-content/themes/
┣ my-theme
┃ ┗ header-logo.png
┃
┗ my-theme-child ← my-themeの子テーマ
┗ header-logo.png ← この画像を使いたい!
こんな場面は、ありそうですね。
親テーマのfunction.phpに次の関数を記述します。
ファイルが存在するかどうかを、確認する関数です。
- function select_theme_file($path,$no_file=false){
- if ( file_exists( STYLESHEETPATH . '/' . $path ) ) {
- return STYLESHEETPATH . '/' . $path;
- }
- if( STYLESHEETPATH === TEMPLATEPATH ) return $no_file;
- return file_exists( TEMPLATEPATH . '/' . $path ) ?
- TEMPLATEPATH . '/' . $path : $no_file;
- }
親テーマのheader.phpで、ロゴ画像のimgタグで関数を呼び出します。
- <img src="<?php select_theme_file('header-logo.png'); ?>">
テストしてないけど、これでいけるはず。
実はWordPressは同じようなファイルチェックをlocate_template()という関数でおこなっています。
関数を自作しなくても、この関数を使うことができます。
- <img src="<?php locate_template('header-logo.png'); ?>">
この関数はテンプレート用に設計されているため、/wp-include/theme-compat/のチェックを行っていたり、テンプレートファイルの読み込みも可能になっています。
テンプレート以外のファイルをチェックするだけなら少し過剰ですが、自作するよりお手軽かもしれません。
■Googleで他サイト検索
■僕がおススメするアフィリエイト教材
■マーケティング施策ツール





こんにちは。