WordPressの高速化や軽量化を試みると、プラグインの利用を控えfunctions.phpにコードを書いて機能を拡張していくことになります。そこで発生するのが、たとえば以下のようなデメリット。

  • 修正するときに該当箇所が探しにくい
  • 同じような機能の関数を書いてしまう
  • アップデートがあるテーマを利用しつつ親テーマのfunctions.phpに追記しているなら、アップデートごとに書いた内容がリセットされてしまう

これらを解決するため、コードを複数のファイルに分割して functions.php にインクルード(組み込み)する方法をおすすめします。

プラグインを使って整理する

視覚的に同等の機能をもつプラグインに「Code Snippets」があります。

プラグインを減らすため functions.php にコードを書き、そのコードを管理するため更にプラグインを増やす…
本末転倒な事態になるため私は使っていませんが、手間の少なさを最優先する方にはいいのかもしれないので一応ご紹介しておきます。

インストール方法

こちらはWordPress公式プラグインなので、例によって2通りの方法があります。

  1. WordPress.orgよりzipファイルをダウンロード
  2. ダッシュボードプラグイン新規追加>「Code Snippets」を検索

Code Snippets の使い方

Code Snippets の設定

Code Snippets の設定

これはインストール直後のデフォルト状態。最下段にプレビューがあるので、視覚的にエディタの調整などを行うことができます。

コードを新規登録

コードを新規登録

問題が起きたときの対処法

プラグインを使っていても functions.php を編集しているという事実は変わりません。画面が真っ白になるなどの不具合が起きたときは、以下の手順を踏みます。

  1. 9行目の内容を wp-config.php に追記してデバッグモードにする

    PHP

    /**
     * 開発者へ: WordPress デバッグモード
     *
     * この値を true にすると、開発中に注意 (notice) を表示します。
     * テーマおよびプラグインの開発者には、その開発環境においてこの WP_DEBUG を使用することを強く推奨します。
     */
    define('WP_DEBUG', false);
     
    define('CODE_SNIPPETS_SAFE_MODE', true);
     
    /* 編集が必要なのはここまでです ! WordPress でブログをお楽しみください。 */
  2. Code Snippets の管理画面から問題のあるコードを無効にする
  3. 1で追記したコードを削除、もしくはコメントアウトしてデバックモードを解除する

プラグインなしで整理する

先に挙げたデメリットの3項目め「アップデートがあるテーマを利用しつつ親テーマのfunctions.phpに追記しているなら、アップデートごとに書いた内容がリセットされてしまう」に該当する方は、事前準備として子テーマを作成し元からあったコードと自分で書いたコードを分ける必要があります。

他者にアップデートされない自作テーマを使っていたり、既に子テーマを使っている場合はもちろん必要ありません。

functions.php を分割してPHPファイルを作る

まずはどのようにコードを分割していくかのルールを決めます。

  • 1機能ごとに細かく分ける
    コードを探す手間がなくなり有効化・無効化が一行コメントアウトするだけになるが、コードのぶんファイル数が増える
  • 機能する場所などで大まかに分ける
    探す手間やコメントアウトの箇所は少し増えるが、ファイル数は少なめに調整できる

ほぼ好みの問題でしょうか…私は後者をとりました。

この分割ルールに則ってファイルを作っていきます。
テキストエディタにコードを貼りつけ、他のテンプレートファイルと被らない「任意の文字列.php」とするのをfunctions.phpが空になるまで繰り返すだけ。

Ex. 私の分割ルール

  • init.php
    初期設定的な関数(セルフピンバック無効、親テーマのCSS読み込みなど)
  • clean.php
    不要なものを削除する関数(WPバージョン情報の非表示、絵文字機能の停止など)
  • content.php
    コンテンツ部分の関数(投稿ページにのみ特定のCSS, JSを出力させるなど)
  • sides.php
    サイドバーやウィジェットの関数
  • custom.php
    その他のごく短い関数

できあがったファイル郡はテーマディレクトリに保存します。

今後の修正などをテキストエディタからのみ行うのであれば「functions」や「includeinc)」、「librarylib)」などの名前をつけたサブディレクトリ(フォルダ)にまとめると分かりやすいです。これらのディレクトリ名はプラグインなどでもよく使われていますね。

ただし、サブディレクトリの中身はブラウザから確認することができません。ダッシュボードの「テーマの編集」から修正を行う可能性がある場合、その他のテンプレートファイルや style.css と同じ階層に置いておきましょう。
各PHPファイル名をfunc-任意の文字列.phpなどにしておくとfunctions.phpの前後にまとめて並べることができます。

インクルードに使う関数

ファイルをインクルードする関数はいくつかあります。

  1. include()
  2. load_template()
  3. locate_template()
  4. get_query_template()
  5. get_template_part()

1番目のみ PHP の関数で、おそらく最も高速です。速さでいうと次点は2番目でしょうか。
しかしどちらも絶対パスの記述が必須なので、親テーマの階層にあるのか、子テーマの階層にあるのか、またサブディレクトリにあるのかをきっちりと記述しなければいけません。

最初、1番目の include() を使おうとしてハマりました。

子テーマの functions.php は親テーマのそれを上書きするものではなく、おおざっぱに言えば既に1度インクルード作業が行われていると捉えることができます。
PHP では実行されているファイルのある階層が常にカレントディレクトリになるという規則があるため、子テーマの functions.php でインクルードを行うと、たとえば先ほど分割したPHPファイル init.php のありかは親テーマのディレクトリだと解釈されてしまうんですね。
__FILE__dirname を使えば正しいパスを渡すことはできますが、WordPressの関数を使えばもっと簡単に記述できます。

推奨されているのが5番目の get_template_part() です。

ソースを覗いてみると locate_template() を使用しているのが分かります。相対パスでよく、まず子テーマのディレクトリを検索してから親テーマの検索をしてくれる、ということで子テーマでこれを行いたいのであれば非常に便利!

WordPressのバージョンが3.0以降であれば使えますので、私はこちらをおすすめします。

functions.php にインクルードする

では、この get_template_part() を使って分割した PHP ファイルをインクルードしていきましょう。

  • サブディレクトリ(lib と仮定)にまとめた {slug}-{name}.php を読み込む場合
    サブディレクトリにまとめる場合

    PHP

    get_template_part( lib/$slug, $name );
    
  • サブディレクトリにまとめず、その他のテンプレートファイル群と同じディレクトリにある {slug}-{name}.php を読み込む場合
    サブディレクトリにまとめない場合

    PHP

    get_template_part( $slug, $name );
    

パラメータ$nameは任意なので、仮にinit.phpというファイルを読み込む場合は以下のように省略できます。

PHP

get_template_part( 'init' );

こうして分割したすべてのPHPファイルをfunctions.phpにインクルードすれば整理は完了です。機能を停止したくなったときもこの関数を一行分コメントアウトするだけ。

CSS ファイルや Javascript ファイルのように分割することで表示が遅くなるものではないので、functions.phpの肥大化が気になる方はぜひ試してみてください。

なお、自分が実践するにあたってインクルード関数について勉強し直しましたが、もし間違っている箇所や別のベストプラクティスがあれば教えていただけると嬉しいです。

WordPress