先日、「WordPress-子テーマの作り方」という記事を書きました。そこではstyle.cssのことだけ触れていましたが、今回はfunctions.phpを使ってカスタマイズする方法について書きたいと思います。
functions.phpは子テーマで同じ関数を定義すると必ず二重定義エラーになると思っていた
子テーマで色々カスタマイズをしてきて、home.phpやsingle.phpその他に手を入れたいときは親テーマからそれらのファイルを子テーマにコピーしてきてそのファイルを修正するという方法でうまくいっていました。同じ方法を functions.php で行うと二重定義エラーがでてしまい上手く行きませんでした。検索するとfunctions.phpは追記されるので同じ関数を指定してはだめということでした。
カスタマイズについての記事を書こうと思って確認のため、codexを調べていたら、
style.css と違い、functions.php は同名ファイルでオーバーライドできません。その代わり、親の functions.php に追加して読み込まれます。正確にいうと、親テーマの functions.php の直前に読み込まれます。したがって、もし親テーマの functions.php で favicon_link() という関数があるとき、子テーマのfunctions.php で同名の関数があれば、子テーマの関数が使用されます。
という記述を発見して あれ?子テーマに同じ名前の関数を書いたらそちらが実行されるのか?私勘違いしていたのかな~でもエラーになったような…テーマによって違うのだろうか、といろいろ思いました。
twentyfourteenのfunctions.phpで多重定義について確認してみる
今子テーマの親テーマとしているのはtwentyfourteenです。functions.phpを見てみました。
function twentyfourteen_setup() {
という関数の前で、
if ( ! function_exists( 'twentyfourteen_setup' ) ) :
というif文を書いてあり、twentyfourteen_setupという関数が既に定義されていれば展開しないようになっています。これがcodexに書いてあった
親テーマの functions.php で favicon_link() という関数があるとき、子テーマのfunctions.php で同名の関数があれば、子テーマの関数が使用されます。
を実現させる仕組みだと思います。ですので、子テーマのfunctions.phpに
function twentyfourteen_setup() { exit('this is child theme twentyfourteen_setup'); }
と書いて実行すれば
このように子テーマの方の twentyfourteen_setup が呼び出されて、二重定義エラーも出ていないことが分かります。
それでは function_exists がfunctionの前に書いてない、functionを子テーマで定義してみます。
function twentyfourteen_wp_title( $title, $sep ) { exit('this is child theme twentyfourteen_wp_title'); }
これで実行をすると以下のエラーとなります。
Fatal error: Cannot redeclare twentyfourteen_wp_title() (previously declared in C:\xampp\htdocs\ryuswp\wp-content\themes\twentyfourteen-usagi\functions.php:6) in C:\xampp\htdocs\ryuswp\wp-content\themes\twentyfourteen\functions.php on line 492
これはfunctionを二重定義している、というエラーです。
このようにtwentyfourteenの関数の中には「二重定義を予防している」「二重定義を予防していない」という2種類の関数があるようです。
二重定義を予防している関数は、
twentyfourteen_setup
twentyfourteen_the_attached_image
twentyfourteen_list_authors
の3つでした。これらについてはそのまま、子テーマに同じ名前の関数を作ればそちらが活かされるようです。
二重定義エラーになる関数をカスタマイズしたいときはどうするか?
先ほど二重定義エラーになった twentyfourteen_wp_title をカスタマイズしたいと思います。
まず、親テーマのfunctions.phpから
function twentyfourteen_wp_title( $title, $sep ) { global $paged, $page; if ( is_feed() ) { return $title; } // Add the site name. $title .= get_bloginfo( 'name', 'display' ); // Add the site description for the home/front page. $site_description = get_bloginfo( 'description', 'display' ); if ( $site_description && ( is_home() || is_front_page() ) ) { $title = "$title $sep $site_description"; } // Add a page number if necessary. if ( $paged >= 2 || $page >= 2 ) { $title = "$title $sep " . sprintf( __( 'Page %s', 'twentyfourteen' ), max( $paged, $page ) ); } return $title; } add_filter( 'wp_title', 'twentyfourteen_wp_title', 10, 2 );
この部分を子テーマのfunctions.phpにコピーします。
この関数はhtmlのtitle部分に出力される文字列を編集しているところのようですので、例としてそのtitle全てに _usagi という文字列を追加するカスタマイズをします。
$title .= get_bloginfo( 'name', 'display' );
の下に
$title .= '_usagi';
という行を追加します。
関数名を twentyfourteen_wp_title から twentyfourteen_wp_title_usagi に変えます。違う名前なら何でもいいのですが。
add_filter行の2つめのパラメータを今名前を変更した twentyfourteen_wp_title_usagi とします。3つめのパラメータは優先度を表しています。10を5に変更します。
これらを変更した結果がこうなります。
function twentyfourteen_wp_title_usagi( $title, $sep ) { global $paged, $page; if ( is_feed() ) { return $title; } // Add the site name. $title .= get_bloginfo( 'name', 'display' ); $title .= '_usagi'; // Add the site description for the home/front page. $site_description = get_bloginfo( 'description', 'display' ); if ( $site_description && ( is_home() || is_front_page() ) ) { $title = "$title $sep $site_description"; } // Add a page number if necessary. if ( $paged >= 2 || $page >= 2 ) { $title = "$title $sep " . sprintf( __( 'Page %s', 'twentyfourteen' ), max( $paged, $page ) ); } return $title; } add_filter( 'wp_title', 'twentyfourteen_wp_title_usagi', 5, 2 );
これで再度読み込み直すと
このようにtitleの部分の後ろに _usagi と追記され、子テーマのfunctions.phpでのカスタマイズができたことが分かります。
二重定義になってしまう関数についてはこのように、子テーマにコピーして関数名を変更。add_filterの関数名を変更すると共に優先順位の数字を小さくするという方法でカスタマイズできるようです。
テーマによって「二重定義を予防している」「二重定義を予防していない」は異なるかと思いますので、子テーマを作成する際はそれぞれの親テーマのfunctions.phpで確認してみてください。
コメント