【2022年】WordPressのfunctions.phpを分割する整理術(子テーマ対応)

WordPress

Posted  Updated 

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

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

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

プラグイン「Code Snippets」を使って整理する

視覚的に同等の機能をもつプラグインに「Code Snippets」があります。関数だけでなく、本文中で使用するショートコードも登録可能。

インストール方法

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

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

設定

General

見出し原文解説
Activate by Defaultスニペットを保存したとき、デフォルトで有効化するか
Enable Snippet Tagsスニペット一覧画面に分類タグを表示するか
Enable Snippet Descriptionsスニペット一覧画面に説明文を表示するか
Snippets List Orderスニペット一覧画面のデフォルト順序。
Priority:個別の優先順位
Name (A-Z):名称のアルファベット順
Name (Z-A):名称の逆アルファベット順
Modified (latest first):更新日の昇順
Modified (oldest first):更新日の降順
Disable Shortcode Syntax Highlighterシンタックスハイライトを向こうにするか
Complete Uninstall「Code Snippets」をアンインストールするとき、すべてのスニペットとプラグイン設定も削除するか

Description Editor

見出し原文解説
Row Heightスニペットの説明文を入力するエディタの高さ(何行分か)
Use Full Editorビジュアルエディタのすべての機能を有効化するか
Media Buttonsメディアの追加ボタンを有効化するか

Code Editor

見出し原文解説
Themeコードエディタのテーマを Monokai などから選択
Indent With Tabsインデントはタブを使用するか
Tab Sizeインデントをタブにするときのタブ文字の幅
Indent Unitインデントをスペースにするときのスペース数
Wrap Lines長い行を右端で折り返すか
Line Numbers行番号を表示するか
Auto Close Brackets入力時、括弧と引用符を自動的に閉じるか
Highlight Selection Matches現在選択されているすべてのインスタンスをハイライト表示するか
Highlight Active Line編集中の行をハイライト表示するか
Editor Previewここまでのエディタ設定のプレビュー

関数の登録・編集・削除

スクリーンショット:サンプル「Allow smiles」の編集画面
  1. スニペットのタイトルを入力します。
  2. コードを記述します。
  3. 実行場所/タイミングを選択します。左から「すべての場所」、「管理画面のみ」、「フロントエンドのみ」、「一度だけ」。
  4. 優先順位を設定します。設定でPriority順を選択していた場合、この数値によりスニペット一覧画面での並び順が変わります。
  5. スニペットの説明文を入力します。
  6. スニペットを分類するためのタグを入力します。
  7. 左から「変更を保存して有効化」、「変更を保存」、「ダウンロード」、「エクスポート」、「削除」。

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

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

  1. 9行目の内容を wp-config.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. 私の分割ルール

ファイル名内容
func-init.php初期設定的な関数(絵文字機能の停止、セルフピンバッグ無効など)
func-breadcrumb.phpパンくずリストの出力
func-write.phpGutenbergのカスタムブロック追加など
func-dashboard.phpダッシュボード内のカスタマイズ
func-form.phpメールフォームのカスタマイズ
form-shortcode.phpショートコードの登録
form-posttype.phpカスタム投稿タイプ、タームなどの登録

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

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

インクルードに使う関数

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

  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() を使用しているのが分かります。相対パスでOK、まず子テーマのディレクトリを検索してから親テーマの検索をしてくれる、ということで子テーマでこれを行いたいのであれば非常に便利!

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

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

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

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

get_template_part( lib/$slug, $name ); 

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

get_template_part( $slug, $name ); 

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

get_template_part( 'init' );

こうして分割したすべてのPHPファイルをfunctions.phpにインクルードすれば整理は完了です。

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