functions.phpで制御しきれない部分を子テーマで補う方法|現場で使える実践テクニック
こんにちは!
今日は「WordPressの子テーマで親テーマのfunctions.phpをうまく上書きする方法」について解説します。
親テーマのfunctions.phpが上書きされない理由
僕も最初めっちゃ戸惑ったんですよ。
子テーマのfunctions.phpを作って、親テーマの関数を上書きしようとしたら、全然効かへんかった。
理由はシンプルで、functions.phpはテンプレートファイルと違って「テンプレート階層」の対象やないんです。
WordPressは読み込み順序が決まってます。
子テーマのfunctions.phpも親テーマのfunctions.phpも、どちらも読み込まれるんですよ。
でも読み込まれる順序は「親テーマ → 子テーマ」です。
つまり、両方の関数定義が実行されてしまうわけです。
もし親テーマでfunction my_custom_function() { ... }っていう関数があったら、子テーマで同じ名前の関数を定義しても、既に親テーマで定義済みだから、子テーマのコードは実行されへんってわけなんです。
子テーマで関数を安全に置き換える実装方法
では、どうするか。
ほんま大事なのは「条件付きで関数定義を制御する」ことなんですよ。
親テーマのfunctions.phpがこんな感じやったとしましょう:
<?php
function my_theme_header() {
echo '親テーマのヘッダー';
}
add_action( 'wp_body_open', 'my_theme_header' );
?>
これを子テーマで上書きしたい場合は、子テーマのfunctions.phpでこう書くといいですよ:
<?php
// 親テーマの関数が定義されている場合のみ、処理をフック
if ( function_exists( 'my_theme_header' ) ) {
remove_action( 'wp_body_open', 'my_theme_header' );
}
function my_theme_header() {
echo '子テーマでカスタマイズしたヘッダー';
}
add_action( 'wp_body_open', 'my_theme_header' );
?>
ポイントはremove_action()で親テーマのアクションをいったん外してから、子テーマの新しい関数を登録するってことです。
こうすることで、意図した処理だけが実行されるわけです。
もっと簡潔にしたい場合は、親テーマの関数を最初からif ( ! function_exists() )で条件付けしてくれてたら、子テーマで先に定義できます。
親テーマがこう書いてるなら:
<?php
if ( ! function_exists( 'my_theme_header' ) ) {
function my_theme_header() {
echo '親テーマのヘッダー';
}
}
add_action( 'wp_body_open', 'my_theme_header' );
?>
子テーマで同じ関数を先に定義すれば、親テーマの定義はスキップされます。
これはめっちゃクリーンな方法やん。
現場でよくある失敗パターンと対策
現場でよく見るのは、ほんまこれなんです。
子テーマで関数をコピペして変更したけど、何も変わらへんって相談を受けることめっちゃあります。
もう一つ大事なのが「フックのタイミング」です。remove_action()でアクションを外すなら、それより前に親テーマが実行されたら意味ないんですよ。
だから子テーマのfunctions.phpで処理する場合、確実に親テーマより後に実行されるように、wp_loadedとかinitフックを使うといいですよ。
それと、もし親テーマがフィルターを使ってたら話は別です。
フィルターの場合はadd_filter()で簡単に上書きできます。
例えば親テーマがapply_filters( 'my_theme_title', $title )って処理してるなら、子テーマでadd_filter( 'my_theme_title', 'my_custom_title_function' )で対応できるわけです。
これはアクションより融通が効きやすいんですよ。
あと、デバッグのコツとしては、子テーマで変更が効いてるか確認するときに、一度関数の中にerror_log()を入れてログで確認するといいですよ。
実際に実行されてるか確認できるので、めっちゃ便利です。
まとめ
子テーマで親テーマのfunctions.phpをカスタマイズするには、ただコピペするだけじゃなくて、きちんとした手順が必要やってわけです。
remove_action()とadd_action()の組み合わせを使うか、親テーマが最初からif ( ! function_exists() )で条件付けしてくれてるのを活用するか。
もしくはフィルターを使って柔軟に値を変更するか。
この3つの方法を場面に応じて使い分けるといいですよ。
テーマ開発は最初めっちゃ試行錯誤が必要ですけど、こういう基本をおさえておくと、後々の改修がほんまに楽になります。
ぜひ実装してみてください。
Web制作で困ったことがあったら、またこのブログを覗いてくださいね!
― クリオ