カスタマイズが開かない原因は Plugin Load Filter だった:止めたあとは Contact Form 7 と TablePress をテーマで絞る

広告WordPress・PHP を学べる本

Amazonのアソシエイトとして、WordPress functions.phpは適格販売により収入を得ています。

管理しているサイトで、管理画面の「外観 → カスタマイズ」が開かなくなっていました。左の項目も右のプレビューも空のままで、タブの題名は「カスタマイズ: 読み込み中…」から変わりません。ブラウザーの開発ツールを見ると、次のエラーが出ていました。

TypeError: Cannot read properties of undefined (reading 'data')
    at i.renderContent (customize-controls.min.js)

投稿の編集やプレビューは普通に動くので、最初はテーマかメニューの設定が壊れたのかと考えました。ところが原因は、ページごとに読み込むプラグインを絞る「Plugin Load Filter」でした。このプラグインを止めて、絞り込みの代わりをテーマに書いた手順と、止める前と後の速さをまとめます。

何が起きていたか

Plugin Load Filter は、有効にすると mu-plugins の中に plf-filter.php というファイルを置き、そこでプラグインの読み込みを絞ります。このファイルは、絞り込みのために WordPress の wp_get_current_user() などのログインまわりの関数を差し替えていて、テーマが読み込まれる前(setup_theme より前)は、ログインしている人でも「ログインしていない人(ユーザー ID 0)」として扱っていました。

カスタマイズの画面は、その早い時点(plugins_loaded)で作られます。そのため、メニューとウィジェットの部品が「この人には edit_theme_options の権限がない」と判断し、画面の JS(customize-nav-menus.js・customize-widgets.js)を入れる登録を飛ばしていました。部品のテンプレートだけが残り、中身を描こうとしたところで、上の TypeError になっていたわけです。

止めてみた結果(作業環境)

本番の複製の作業環境で Plugin Load Filter を無効にすると、mu-plugins の plf-filter.php も自動で消え、カスタマイズは普通に開きました。左にメニュー・ウィジェット・追加 CSS などが並び、プレビューも出ます。投稿の編集・お問い合わせ・ほかのページも 200 で、Fatal error や Warning は出ませんでした。

ただ、絞り込みがなくなるので、Contact Form 7 と TablePress の JS・CSS がどのページでも読まれるようになります。トップでは script が 14 から 21 に、CSS が 2 から 4 に増えました。そこで、絞り込みの代わりをテーマの functions.php に書きました。

使うページだけで読むコード

Contact Form 7 は wpcf7_load_js・wpcf7_load_css のフィルターで、フォームのあるページだけ読むようにします。TablePress 3 には、表を出したときだけ CSS を読む仕組みがあるので、古い読み方を止めるフィルターを 1 行足すだけです。もう 1 つ、Site Kit by Google は Contact Form 7 が有効だとフォームの計測の JS をどのページにも足すため、これもフォームのないページでは外します。

functions.php(テーマ)
// 本文かページビルダーに、決まった文字(ショートコードの名前)があるか
function my_current_page_has( $needle ) {
    if ( ! is_singular() ) {
        return false;
    }
    $post = get_queried_object();
    if ( ! ( $post instanceof WP_Post ) ) {
        return false;
    }
    if ( false !== strpos( (string) $post->post_content, $needle ) ) {
        return true;
    }
    // テーマのページビルダーに本文を持たせている場合は、そちらも見る
    $builder = get_post_meta( $post->ID, 'page_builder', true );
    if ( '' === $builder || null === $builder ) {
        return false;
    }
    $text = is_string( $builder ) ? $builder : wp_json_encode( $builder );
    return false !== strpos( (string) $text, $needle );
}

// Contact Form 7:フォームのあるページだけで JS・CSS を読む
function my_wpcf7_load_assets( $load ) {
    // 管理画面や、まだページが決まっていないときは今までどおり読む
    if ( is_admin() || ! did_action( 'wp' ) ) {
        return $load;
    }
    return $load && my_current_page_has( '[contact-form-7' );
}
add_filter( 'wpcf7_load_js', 'my_wpcf7_load_assets' );
add_filter( 'wpcf7_load_css', 'my_wpcf7_load_assets' );

// TablePress:全部のページで CSS を読む古い読み方をやめ、表を出したときだけ読む
add_filter( 'tablepress_frontend_legacy_css_loading', '__return_false' );

// Site Kit:Contact Form 7 が有効だと、どのページにもフォームの計測の JS を足すので、
// フォームのないページでは外す(Site Kit は 30 番目で足すので、100 番目で外す)
function my_dequeue_sitekit_cf7() {
    if ( ! my_current_page_has( '[contact-form-7' ) ) {
        wp_dequeue_script( 'googlesitekit-events-provider-contact-form-7' );
    }
}
add_action( 'wp_enqueue_scripts', 'my_dequeue_sitekit_cf7', 100 );

迷ったときは読む側に倒しています。管理画面と、ページが決まる前(wp のアクションより前)は今までどおり読むので、フォームが動かなくなることはありません。お問い合わせのページでは、Site Kit のフォームの計測もそのまま動きます。

止める前と後の比べ(作業環境・ログインなし・7 回の真ん中の値)

ページ 止める前 止めただけ 止めて、テーマで絞る
トップ 0.886 秒・script 14・CSS 2 1.057 秒・21・4 0.942 秒・14・2
コラム 0.881 秒・12・1 1.008 秒・19・3 0.982 秒・12・1
ネイルデザイン 0.853 秒・12・1 1.102 秒・19・3 0.956 秒・12・1

script と CSS の数、ページの大きさは止める前と同じに戻りました。最初の 1 バイトが返るまでの時間(TTFB)は 0.06〜0.10 秒ほど遅くなっています。全部のプラグインを毎回読み込むようになったためで、ここは安定と引き換えにしました。

止めるときの手順

  1. Plugin Load Filter の設定の画面を撮っておく(戻すとき用)。
  2. 先にテーマの絞り込み(上のコード)を本番に入れる。
  3. プラグインの画面で Plugin Load Filter を「無効化」する(削除はしない)。mu-plugins の plf-filter.php が消えたかを見る。
  4. カスタマイズが開くか、お問い合わせのフォームと表のあるページ、script・CSS の数を確かめる。
  5. だめなときは、有効にし直せば plf-filter.php も作り直されて元に戻る。

Plugin Load Filter は速さには効いていましたが、ログインまわりの関数を差し替える作りのため、早い時点でログインしている人を見るプラグインや画面とぶつかることがあります。カスタマイズや一部の管理画面がおかしいときは、一度止めて確かめてみてください。

関連機能

  1. WordPress標準のエクスポート・インポートにアイキャッチの画像を含める Export media with selected content プラグイン

  2. WordPress「 & 」のコードが意図していない箇所に表示される場合の対応

  3. Deprecated: Automatic conversion of false to array is deprecated inの対応

サイドバー

よく使うカスタマイズ

最近の記事

Profile

PAGE TOP