functions.php で定義済の関数をオーバーライドする方法 ~WordPress 覚書き~

functions.php内の関数をオーバーライドしようとした時の覚え書き。

WordPressテーマをカスタマイズする際に、どうしてもfunctions.php内の定義済み関数の内容を変えたい場合があると思います。

通常、カスタマイズする際には子テーマを作成して行うと思いますが、functions.phpだけはオーバーライドされないため、親テーマのfunctions.phpの内容を子テーマ内で変更するためにはちょっと工夫が必要です。

対処方法は以下の通りです。

1.修正する関数と同名の関数の定義を、子テーマのfunctions.phpに記述する

この方法ではエラーが出ます。

以前、WordPress Codexでは

style.css と違い、functions.php は同名ファイルでオーバーライドできません。その代わり、親の functions.php に追加して読み込まれます。正確にいうと、親テーマの functions.php の直前に読み込まれます。したがって、もし親テーマの functions.php で favicon_link() という関数があるとき、子テーマのfunctions.php で同名の関数があれば、子テーマの関数が使用されます。

と記載されていたことがありましたが、これは間違いです。(現在では修正されています。)
もしかしたら、上の記述を別のブログの引用などで見たことがある方がいたらと思い、この方法ではできないということを伝えるために書いておきました。

以下が正しい対処方法です。

2.親テーマのfunctions.phpでの関数の記述に、if( ! function_exists())が使われている場合

親テーマのfunctions.phpで関数を定義する際に、if( ! function_exists())が利用されている場合、子テーマのfunctions.phpで同名の関数を記述しても、問題なくオーバーライドされます。(たまたま、私が使っている無料テーマはこの方法を取っていました。)

これは、先に子テーマのfunctions.phpが読み込まれるというルールを上手く利用した書き方ですね。
※if( ! function_exists())は、「もし、同名のfunctionがなければ、定義を続ける」という意味の記述です。

他にも、親テーマの中でif( ! function_exists())を別の形で利用する方法もあるみたいです。
親テーマを作成される方は、こちらも参考リンクを貼っておきます。

参考:子テーマfunctions.phpでの同名関数について

3.子テーマのfunctions.phpに別名で関数を記述した後、フックを使って疑似的に書き換える

無料テーマなどをカスタマイズして使う時に、親テーマの関数にif( ! function_exists())が使われていない場合でも、その関数にadd_actionなどでフックが設定されている時は、疑似的に上書きすることができます。

例えば、カスタマイズしたい親テーマの関数(A)に対して、フックadd_action(‘hoge’,’A’)が設定されていたとします。

まず、子テーマのfunctions.phpで別名(A_child)で関数を記述します。
次に、remove_action(‘hoge’,’A’)を使って親テーマの関数(A)のフックを削除する関数(関数名は任意)を記述します。この関数を、親テーマの後に実行するように(after_setup_themeのフックを使って)指定します。

こんな感じです。
かなりざっくりと書きましたが、このようにすれば疑似的にオーバーライド可能です。

参考:
WordPressの子テーマで functions.php 上書き的なこと
子テーマの導入と親テーマへの継承について

子テーマでの運用は便利ですが、注意点も多いので気をつけなくてはですね。。

2017年10月16日追記:
remove_actionを使って疑似的にオーバーライドする方法を実例で書きました。
親テーマのfunctions.php内のrequireの参照先の関数を子テーマで書き換える方法~WordPress 覚書き~