自作プラグインやテーマで、設定画面を作って保存した任意の値をjQueryに反映させたいときに、PHPからjQueryへ値を渡す方法と、がんばってPHPから渡さなくても済むようにする手法を紹介します。

値を渡すjQueryのコードそのものが少ない場合であれば後者を使う方が簡単ですが、それぞれメリットデメリットがありますので、最終的には自身の状況と照らし合わせて判断するとよいでしょう。

【方法1】wp_localize_script()を使ってデータを渡す

この方法はWordPressでjQueryなどのスクリプトを読み込ませる標準の?手法である、外部ファイルに保存したjQueryを、wp_enqueue_scripts関数で読み込ませる場合に適した方法です。

まあご存じかと思いますが、この方法では、最終的に生成されるHTMLソース上では、jQueryファイルへのリンクを出力して内容を読み込むようになっているため、依存関係(jQueryではWordPress標準のjQueryライブラリが読み込まれてから処理される必要がある)を明確にすることで確実に動作するようにしたり、読み込みの一括最適化(deferやasyncを付加するなど)を確実にさせることができるメリットがあります。

ただ、冒頭で書いたように、optionsテーブルなどに保存した値をjQuery側で利用するには、PHPで呼び出した変数(保存した値)をjQueryへ渡す必要があります。

このPHP側の処理では、WordPressの組み込み関数である、wp_localize_script()関数を使うのが一番簡単です。

wp_localize_script()関数を使ったコードの具体例

例として以下のようなPHP側のコード(上)と、別ファイルに書いたjQueryのコード(下)があったとします。

/* スクリプトの読み込み */
function sample_sticky_header_script_include() {
	wp_register_script( 'sticky-header-script', plugin_dir_url( __FILE__ ) .'sticky-header.js', array('jquery'), null,true );

	wp_enqueue_script( 'sticky-header-script');

}
add_action( 'wp_enqueue_scripts', 'sample_sticky_header_script_include' );
jQuery(document).ready(function($) {
$(function () {
	var display = function () {
	var fixContact = $('.is_fix');
	var scrollPositionTop = $(window).scrollTop();

//画面上から200ピクセルを超えるときだけ表示させる
if(scrollPositionTop > 200){
             fixContact.fadeIn(400);
    } else {
            fixContact.fadeOut(400);
    }
    };

  $(window).on('scroll', display);

});
});

上記のコードは実際に本サイトで提供している【Hima Art Utility】プラグインで実装している固定ヘッダーのコードの一部(面倒な処理をすべて省いたもの)で、このページをスクロールした際に固定表示されるヘッダーで使用しているコードの基本となる部分のみを抜粋したものです。

PHP側では、jQueryのあるファイルを「wp_register_script」で登録し、「wp_enqueue_script」でエンキュー(読み込みの指示)をしたものを「wp_enqueue_scripts」へフックして処理を追加しているものです。

まあ、複数個所でエンキューする必要がなければ、「wp_register_script」を省いて「wp_enqueue_script」だけを書くというのが一般的な使い方ですね。

余談ですが、上記コード中で依存関係を「array(‘jQuery’)」と指定することで、WordPressのjQueryライブラリが読み込まれた後で必ずこのスクリプトが読み込まれるようにして、確実に動作するようにしています

そして、jQuery側では以下のような動きをさせるようにしています。

  • ページトップからのスクロール量が200pxを超えたら要素に「is-fix」クラスを追加する
  • 「is-fix」クラスの付いたコンテンツを400ミリ秒でフェードインさせる
  • 逆に「is-fix」から外れたコンテンツを400ミリ秒でフェードアウトさせる

まあすごく短いコードですが、これで200pxスクロールされると何かをフェードインさせて表示し、ページトップから200px以下の位置になったらフェードアウトして消えるという機能が実装できます。

例えば、この「200px」「400ミリ秒」の値を指定した任意の数字に変更して動作させたい、そんな場合に、wp_localize_script()を使用します。

PHP側の変更

まずは、PHP側の変更後のコードです(以下のコードの赤字部分が追加した部分です)。

/* スクリプトの読み込み */
function sample_sticky_header_script_include() {
	wp_register_script( 'sticky-header-script', plugin_dir_url( __FILE__ ) .'sticky-header.js', array('jquery'), null,true );

	wp_enqueue_script( 'sticky-header-script');


//PHPからJSへ値を渡す
$start_position = get_option('オプションのキー',false);
$fadein_speed = get_option('オプションのキー',false);
$fadeout_speed = get_option('オプションのキー',false);
	
	if(empty($start_position)){
		$sposition = '200';
	}else{
		$sposition = $start_position;
	}

	if(empty($fadein_speed)){
		$inspeed = '400';
	}else{
		$inspeed = $fadein_speed;
	}

	if(empty($fadeout_speed)){
		$outspeed = '400';
	}else{
		$outspeed = $fadeout_speed;
	}

		$localize_val = array(
		'scroll_fadein' => $inspeed,
		'scroll_fadeout' => $outspeed,
		'top_distance' => $sposition
		);

		wp_localize_script('sticky-header-script', 'StickHeaderVal', $localize_val);

}
add_action( 'wp_enqueue_scripts', 'sample_sticky_header_script_include' );

いきなり超絶増えてますね(笑)。順に解説していきます。

まず、上のコードでは、以下の3つのオプション値をjQueryへ渡そうとしていて、ひとまずoptionsテーブルに保存した値を以下の変数に格納しています。

  1. 固定ヘッダーを表示させるページ上部からの位置 $start_position
  2. フェードインさせる時間(ミリ秒) $fadein_speed
  3. フェードアウトさせる時間(ミリ秒) $fadeout_speed

そして、optionsテーブルに値がなかったら(if(empty)の部分の条件分岐)、1は200、2は400、3は400をそれぞれ代入したものを、値があればそれを「$sposition」「$inspeed」「$outspeed」へ格納しなおすようにしています。

最後にwp_localize_script()を使って、値を渡す準備をしています。

wp_localize_script()は原則以下のように各パラメーターを指定します。

wp_localize_script('渡すスクリプトのハンドル', '認識する文字列', 渡す変数(またはコールバック));

上記のコードでは、wp_enqueue_scriptのハンドルが「渡すスクリプトのハンドル」になるので「sticky-header-script」、変数は他のwp_localize_script()と被らないようにする必要があるので「StickHeaderVal」という値を(これは自身の環境に合わせて任意で構いません)、渡す変数は、複数あるので、一旦「$localize_val」という変数に格納して指定しています。

wp_localize_script()の原則

wp_localize_script()関数を使う際には、必ず先に「渡すスクリプト」が登録(wp_register_script)またはエンキュー(wp_enqueue_script)されている必要があります。上記コードでは、同じユーザー定義関数(sample_sticky_header_script_include)内で順序立ててフックさせていますが、順番を守れば別のユーザー定義関数にしても構いません。

また、先ほど少し触れましたが「認識する文字列」は、誤動作を避けるため、他のwp_localize_script()を使ったコードの「認識する文字列」と確実に区別できるようにし、半角英数字(大文字・小文字)と「_(アンダーバー)」のみを使用する必要があります。

jQuery側の変更

続いて、jQueryコードを変数を受け取って処理するように書き換えます。

以下が書き換え後のコードです(赤字部分が変更した箇所です)。

jQuery(document).ready(function($) {
$(function () {
	var display = function () {
	var fixContact = $('.is_fix');
	var scrollPositionTop = $(window).scrollTop();
	//PHPから受け取った値をNumberで数値に戻す
	var scrollFadein = StickHeaderVal.scroll_fadein;
	var scrollFadeout = StickHeaderVal.scroll_fadeout;
	var TopDistance = StickHeaderVal.top_distance;

//画面上から200ピクセルを超えるときだけ表示させる
if(scrollPositionTop > TopDistance){
             fixContact.fadeIn(scrollFadein);
    } else {
            fixContact.fadeOut(scrollFadeout);
    }
    };

  $(window).on('scroll', display);

});
});

「var」宣言で、変数ですよ!とした上で以下の値を受け取るようにさせます。

  • 「StickHeaderVal.scroll_fadein」の値を「scrollFadein」という変数に格納
  • 「StickHeaderVal.scroll_fadeout」の値を「scrollFadeout」という変数に格納
  • 「StickHeaderVal.top_distance」の値を「TopDistance」という変数に格納

この「StickHeaderVal.scroll_fadein」「StickHeaderVal.scroll_fadeout」「StickHeaderVal.top_distance」は、先ほどPHP側で行った変更の「認識する文字列.渡す変数」がそれぞれ入ります。

後は、最初のjQueryにあった「200」「400」「400」という実数を変数に書き換えれば、PHP側からjQueryに値を渡す措置は完成です。

完成と言いましたが、実は、上のようにしても、渡す値が数字の場合はきちんとした値が渡らず動作しません。その理由と変更方法については次項の「数値として渡す場合は注意が必要」をご覧ください。

うまく動作するかを確認する際に1点だけ注意事項があります。それは、JSは通常の再読み込みではリフレッシュされないことです。動作確認する際は、「Ctrl」+「F5」を使ってキャッシュをクリアしてください。

数値として渡す(利用する)場合は注意が必要

wp_localize_script()関数は、もともと翻訳文字列をPHPとJSの間でやり取りするための関数で、JS(JavaScriptやjQuery)に渡して使用されるデータはすべて文字列扱いになります。が、実際の使用シーンでは、URLなどの文字列を渡すよりも、プラグインの設定画面で指定した数字を適用する場合の方が個人的には多いように感じます。

従って数字を指定する部分へそのままデータを渡しても、文字列なのでJS側が??となってしまいうまく変更されないという事態が発生します。

これを解消するためには、JS側でデータを受け取った際に数字へ戻すという措置が必要になります。具体的には以下のようにします。

普通にデータを受け取る場合のコード例が以下です。

var 変数名 = オブジェクト名.キー;

そして、数字に戻すための措置をしたコード例が以下です。

var 変数名 = Number(オブジェクト名.キー);

そう、分かってしまえばなーんだってことなんですけど、結構これが分からなくて時間を使いました(笑)。Number()で囲むだけなんですね。ちなみにNumberは数値ですが、整数と指定するものなどいろいろあるので、ご自身で調べてみてください。


参考:wp_localize_script(文字列 $handle、 文字列 $object_name、 配列 $l10n )

【方法2】そもそもPHPでjQueryを出力する

短いjQueryコードならPHPで書いて出力したほうが簡単です。というか、前項のwp_localize_script()を使う方法をちょっと見て「.....」となってしまった方はこちらをまず試してみるといいかも知れません。

この方法のメリットは、まず簡単なことと、行っていることが明確なので、確認しやすいことです。

逆にデメリットとしては、HTMLソース上にコードが丸裸に書かれてしまうこと(あまり気にする必要もないかとも思いますが..)と、jQueryでWordPressのライブラリを使う場合に依存関係が明確でないため、動作しない場合が発生したり、ライブラリの重複読み込み処理を命令することになる場合があるので、表示速度に影響が出る可能性があることでしょう。

以下例を2つ紹介しますが、結果は同じ、機能も前項のwp_localize_script()を使った場合と同じです。

【例1】body閉じタグ前に直接出力する

//jQueryの読み込みが終わってなかったら、強制的に先に読み込ませる
function my_enqueue_scripts() {
	if ( !wp_script_is( 'jquery', 'done' ) ) {
		wp_enqueue_script( 'jquery' );
	}
}
add_action( 'wp_enqueue_scripts', 'my_enqueue_scripts' );

//スクリプトをbody閉じタグ前へ出力
function sample_footer_script_init() {

//optionsテーブルから値を抽出
$start_position = get_option('オプションのキー',false);
$fadein_speed = get_option('オプションのキー',false);
$fadeout_speed = get_option('オプションのキー',false);

?>
<script>
jQuery(document).ready(function($) {
$(function () {
	var display = function () {
	var fixContact = $('.is_fix');
	var scrollPositionTop = $(window).scrollTop();

//画面上から200ピクセルを超えるときだけ表示させる
if(scrollPositionTop > <?php echo $start_position; ?>){
             fixContact.fadeIn(<?php echo $fadein_speed; ?>);
    } else {
            fixContact.fadeOut(<?php echo $fadeout_speed; ?>);
    }
    };

  $(window).on('scroll', display);

});
});
</script>
<?php
}
add_action( 'wp_footer', 'sample_footer_script_init', 10000 );

【例1】body閉じタグ前にエンキューして出力する

function sample_footer_script_enqueue() {
	if( !wp_script_is( 'jquery', 'done' ) ) {
		wp_enqueue_script( 'jquery' );
	}

//optionsテーブルから値を抽出
$start_position = get_option('オプションのキー',false);
$fadein_speed = get_option('オプションのキー',false);
$fadeout_speed = get_option('オプションのキー',false);

$script = "
jQuery(document).ready(function($) {
$(function () {
	var display = function () {
	var fixContact = $('.is_fix');
	var scrollPositionTop = $(window).scrollTop();

//画面上から200ピクセルを超えるときだけ表示させる
if(scrollPositionTop > $start_position ){
             fixContact.fadeIn( $fadein_speed );
    } else {
            fixContact.fadeOut( $fadeout_speed );
    }
    };

  $(window).on('scroll', display);

});
});
";

//jquery-migrateハンドルの後に出力
	wp_add_inline_script( 'jquery-migrate', $script, 'after' );
}
add_action( 'wp_enqueue_scripts', 'sample_footer_script_enqueue' );

参考:

後述

ここまで、PHPで取得した値をjQueryへ渡すということについて紹介してきましたが、値を渡すという主旨とは別に、結果的には同じ機能を持たせるjQueryもいろいろな書き方があって、それに対してどうするか?というパターンが、本ページの場合でも少なくとも3つあることがお分かりいただけたでしょう。

値の渡し方については、お好みの方法、または、用途に合わせてどれかを選択すれば、いずれも動作しますから問題ありませんので、自身のコードパターンがどれなのかを把握した上で対処してみてください。