[WordPress] WordPressからPHPの値を特定のページのJavaScriptへ渡す方法

WordPress

Nプログラマです。

WordPressを使っていると、PHPで取得した値を加工してからページのJavaScriptへ値を渡したいケースがあります。
そういう時は、wp_localize_script関数を使うことが多いと思います。
また自作でPHPのecho関数を使って、<script>タグから始まるJSを文字列として定義して渡すという方法もありますよね。

しかし、いずれにせよ全ページに値が渡ってしまうので、特定のページのみしたいというケースも出てきます。
小さなデータだったらいいですが、毎回大きなデータだと使わないページでも値を渡す処理が入ってしまい、ページ読み込みが遅くなる可能性もあります。

今回は特定のページに値を渡す分岐処理を、カスタムフィールドを使って制御するという内容で、備忘録として残しておきます。

今回試したWordPressの検証環境は、バリューサーバー【まるっとプラン】 です。
よく検証環境の餌食になってます。

概要

目標

  • WordPress内で使うPHPの値を、特定のページのJavaScriptに渡す

前提条件

WordPressはインストール、設定済み

やってみた

全ページでPHPの値をJavaScriptへ渡す処理

まずは全ページに値を渡す方法を作ってみます。
ここで使うWordPress関数は以下の通りです。
各関数については、リンク先のドキュメントを参照してください。

get_post_type投稿と固定ページを判別するために使います。
wp_enqueue_script表示するページにJavaScriptファイルを読み込ませるために使います。
wp_localize_scriptwp_enqueue_scriptで読み込んだJavaScriptファイルに
PHPの値を渡すために使います。

こちらが作ってみたコードです。
funciton.phpに記述しているので、バックアップを取っておきましょう。
値を渡すためのsample.jsは、事前に空ファイルをfunction.phpと同じ階層に作成しておきます。
JavaScriptへ渡すためのデータ($js_values)が固定になっていますが、ここは実装方法によりデータが異なるので読み替えてください(データベースから取得したデータ等)

add_action('wp_enqueue_scripts', function() {
    $post_type = get_post_type();
    // 投稿と固定ページ以外のページは何もしない
    if (! in_array($post_type, ['post', 'page']))
        return;

// START: PHPの値をJavaScriptへ渡す処理
    $handle_name = 'sample_data';
    // 値を受け取るJavaScriptファイル
    $js_file_path = get_stylesheet_directory_uri().'/sample.js';
    wp_enqueue_script($handle_name, $js_file_path, ['jquery']);

    // JavaScriptへ渡すためのデータ
    $js_values = [
        'name' => 'sample_name',
        'age'  => 20,
    ];

    // 値を受け取るJavaScript内にjs_valuesという変数へ、$js_valuesの値を渡す
    wp_localize_script($handle_name, 'js_values', $js_values);
// END: PHPの値をJavaScriptへ渡す処理
});

これで投稿か固定ページのhtml内に、js_valuesという変数に$js_valuesがJSONに変換された内容が入っていることを確認できると思います。

次はこの処理を少し手を加えて、特定のページのカスタムフィールドからPHPの値を渡すかのフラグを取得して、読み出し判定をする処理にしてみます。

特定のページにPHPの値をJavaScriptへ渡す処理

準備

最初に、PHPの値を渡したい特定のページのカスタムフィールドを設定しておきます。

カスタムフィールド名はis_use_dataとします。ページにPHPの値を渡したい時は、trueを入れておきます。

WordPressの管理画面から、特定のページの編集画面でこのようにカスタムフィールドを設定してあげます。

カスタムフィールドの画像

準備が整ったので、先程のソースコードの修正版を見ていきます

修正版ソースコード

add_action('wp_enqueue_scripts', function() {
    $post_type = get_post_type();
    // 投稿と固定ページ以外のページは何もしない
    if (! in_array($post_type, ['post', 'page']))
        return;

// PHPの値をJavaScriptへ渡す処理: START
    // 追加したところ: START
    global $post;
    $is_use_data = get_post_meta($post->ID, 'is_use_data', true);
    // 記事のカスタムフィールドのis_use_dataが未設定なら何もしない
    if ( ($is_use_data != true) || empty($is_use_data) )
        return;
    // 追加したところ: END

    // データの読み込み処理
    $handle_name = 'sample_data';
    // 値を受け取るJavaScript
    $js_file_path = get_stylesheet_directory_uri().'/sample.js';
    wp_enqueue_script($handle_name, $js_file_path, ['jquery']);

    // JavaScriptへ渡すためのデータ
    $js_values = [
        'name' => 'sample_name',
        'age'  => 20,
    ];

    // 値を受け取るJavaScript内にjs_valuesという変数へ、$js_valuesの値を渡す
    wp_localize_script($handle_name, 'js_values', $js_values);
// PHPの値をJavaScriptへ渡す処理: END
});
追加部分の説明

追加したのは、以下の処理です。

// 追加したところ: START
global $post;
$is_use_data = get_post_meta($post->ID, 'is_use_data', true);
// 記事のカスタムフィールドのis_use_dataが未設定なら何もしない
if ( ($is_use_data != true) || empty($is_use_data) )
    return;
// 追加したところ: END

get_post_meta関数で、投稿に紐付いているカスタムフィールド(is_use_data)を取得しています。
第三引数をtrue指定することで、配列ではなく文字列で取得できます。(指定しないとfalseがデフォルト値なので注意)

「PHPの値を渡すページのみフラグの設定する」という使い方がしたいので、未設定の場合の判定処理にempty関数を使っています。(get_post_meta関数の第三引数がtrueだと、未設定の場合は空文字が返ってくるため)
このようにしておくと、使わないページにis_use_dataのいちいち設定しなくてよいので楽です。

またtrueではない判定は緩い比較にしているので、ここはお好みで変更してみてください。

これでPHPの値を渡すページと渡さないページを作成して、htmlをチェックしてみましょう。

期待通りになっていればオッケーです。

お疲れ様でした。

考察

今回はis_use_dataが未設定なら何もしないという処理にしていますが、複数の値を見るようにすれば、色々と処理を切り替えることができると思います。

デメリットは、カスタムフィールドを割り当てたページが探しづらいことですね。
検索用処理をプラグイン使ったり、自作する必要が出てきそうです。

終わりに

今回は、WordPressからPHPの値を特定のページのJavaScriptへ渡すという内容でした。

当初、特定のページへの割り当て判定は投稿IDで判定していたのですが、いちいち投稿IDを調べてソースコードを変更するのが面倒になってきて作ったというのがきっかけだったりします。

ただあまりカスタムフィールドが増えすぎると管理が大変になってくるので、別のアプローチが必要なるんじゃないかなーと思ったなんかして。。。

その時がきたら、また考えることにしましょう。

それでは、このへんで。
バイナリー!

タイトルとURLをコピーしました