WordPressの子テーマを作成する時にハマった3つのこと

photo credit: thisismyurl via photopin cc
photo credit: thisismyurl via photopin cc

「WordPressの子テーマ作成なんて簡単だろ!ウヒヒ」と侮っていたらハマったお話です。根本的な作成方法は変わらないんですけどね。

3つの点で躓きました。

 「Template 」の指定はフォルダ名で

子テーマとして認識させるにはstyle.cssが必要です。このスタイルシートには最低限、

という2行の記述をしておく必要があります。この「Template」の項目は親テーマのフォルダ名を指定しましょう。間違えると以下のエラーが発生してしまいます。

「壊れているテーマ

以下のテーマはインストールされていますが不完全です。テーマにはスタイルシートとテンプレートが一つずつ必要です。

親テーマが見つかりません。”◯◯” の親テーマをインストールしてください。」

例えば僕は「Template」の項目に親テーマの名前(style.cssで設定されたテーマ名)を入力しちゃいました。これじゃあ駄目なんですね。ちゃんとフォルダ名を指定しましょう。

child-theme-bewildered01
こんなエラー出ます

テーマディレクトリを取得する関数に注意

CSSやJavascriptを読み込むためにURL指定する時、テーマのディレクトリを取得するためget_template_directory_uri()を使いますよね。

しかし、この関数を子テーマのテンプレートで使用すると親テーマのディレクトリURLが返ってきてしまいます

じゃあどうするのかというと、子テーマではget_stylesheet_directory_uri()を使えば子テーマのディレクトリURLが返ってきます。ええ、僕はコレちょっとハマりました。

参考: 関数リファレンス/get stylesheet directory uri – WordPress Codex 日本語版

functions.phpは上書きされない

基本的に子テーマは(親テーマのテンプレートを継承するので)style.cssだけで動きます。

WordPressに必要なテンプレートが子テーマに無い場合、親テーマのテンプレートを参照します。そして手を加えたいテンプレートのみ、親テーマから子テーマのフォルダへコピーして書き変えます。子テーマにテンプレートがあった場合、親テーマのテンプレートが上書きされるイメージです。褒め言葉ですが、都合の良い機能ですね。

そんな感じで必要なテンプレートをどんどん親テーマからコピーしちゃって良いのですが、1つだけ例外があります。それはテーマ用の関数をまとめるfunctions.phpです。

functions.phpだけは親テンプレートが上書きされず、

  1. 子テーマのfunctions.php
  2. 親テーマのfunctions.php

という順番で読み込まれる仕様になっています(上書きされません)。なので、例えば継承元の親テーマのfunctions.phpが子テーマ作成に対応したソースコードになっていなければ、テンプレートをそのままコピーしてしまうとPHPエラーが発生します。

どうしてそのままコピーするとエラーが発生するかというと、上書きされず順番に読み込まれてしまうのでfunctions.phpに書かれた、主に関数が二度定義されることになってしまうのです。関数の二重定義が起こるとPHPはエラーを吐きます。

この問題を解決する方法は3つ

この関数の二重定義を回避する方法は3つあります。それは、

  1. 子テーマのfunctions.phpから関数(やその他被ったら困るソースコード)を削除する
  2. 関数名を変更する
  3. 既に定義されているかを調べるPHPの関数で回避する

です。

1つ目は簡単ですね。というか、特別なことが無ければコピーしてきたfunctions.phpの中身を全部削除しちゃっても良いと思います。「あ、これ必要だった」と気付いたらまたコピペで良いワケですし。

2つ目の関数名を変更するってのもアリだと思います。(というか1つ目と方向性は変わらない)

1,2の方法で大体の場合はOKなんですけど、じゃあ3つ目の「PHPの関数で回避する」ってのはどういう状況で必要かというと、子テーマが作成されることを想定している時なんですね。自分自身がテーマを作成して「あ、これ子テーマ作成されるかもしれないっすわ」と未来を見据えて必要なら、って感じです。

この二重定義を回避するには、関数が既に定義されているか調べる関数function_exists()でif判定する必要があります。

例えば

functions.phpをそのまま子テーマにコピーした例を示してみます。

 親テーマのfunctions.php

親テーマのfunctions.phpが上記のようになっていて、これをそのまま子テーマにコピーするとfunctions.phpの内容は以下のようになります。(もちろん子テーマを有効化している場合ですね)
はい、先述した通り同じ関数が2つ出来上がっちゃうんですね。これでは二重定義となりエラーになります。なので先ほど挙げた関数function_exists()の出番です。この関数に引数として渡した文字列の関数名が既に定義されていた場合、TRUEが返ってくるのでコレを利用します。
こうすることで関数の二重定義を防げます。子テーマが作成される、もしくは作成されるかもしれない場合はこの点に注意したいですね。(WordPressのデフォルトテーマは子テーマが作成されることを想定し、同様の処理がされています)

参考: PHP: function_exists – Manual

最終更新日:2014年9月28日

コメント

「何かそこ違うよ」「こうした方が良い」っていう部分があったら指摘して頂けると嬉しいです。

トラックバック

Trackback: https://increment-log.com/child-theme-bewildered/trackback/