PHP
JavaScript
WordPress

WordPressでJavaScriptを読み込ませるならこうすると便利です(2018年)

はじめに

WordPressでJavaScriptを使う機会があり、読み込ませる方法について検討してみました。

結論を先にまとめると「小さいならadd_action()+無名関数」で、「大きくなったらwp_enqueue_script()」です。

直接読み込ませる

WordPressの公式サイトではheader.phpに記述したりして直接読み込ませる方法が紹介されていますが、header.phpではなくテンプレートごとに記述する方法を取ります。

投稿や固定ページで呼び出す場合

一つのテンプレートファイルだけで使うスクリプトを記載したい場合にはwp_headerswp_footerにフックして書きます。

/**
 * フッターで呼び出し。
 */
add_filter( 'wp_footer', function() {
    ?>
    <script>
        console.log('Hello World!');
    </script>
    <?php
} );

Screen Shot 2018-03-12 at 15.59.11.png
Screen Shot 2018-03-12 at 15.58.28.png

無名関数+PHPの閉じタグ、開始タグと一緒に書くことでヒアドキュメント風に書ける上にエディタがJavaScriptとして認識しやすいので見栄えがスッキリします。

ただしJavaScriptの処理が大きくなって来た場合にはJSファイルとして分離してwp_enqueue_script()で登録します。

enqueue系関数を使って読み込ませる方法

こちらはwp_enqueue_script()で読み込ませる方法です。

関数名 目的
wp_enqueue_script() JavaScriptファイルをロードさせるならこれ
wp_register_script() ロードさせる前に登録させたい場合に使う
wp_localize_script() 変数をページ内にロードさせたい場合に使う
wp_dequeue_script() エンキューをやめる

wp_enqueue_script

よく「WordPress JavaScript」でググると出てくる方法です。
wp_enqueue_script()add_action() で登録した関数に入れたりします。

add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_script( 'wspc',
   plugins_url( '/js/wspc.js', __FILE__ ),
    array( 'jquery' ) );
});

特に理由がなければheader.php<script src="...">で直接記載するよりwp_enqueue_script()を使う方が良いです。
JavaScriptファイルのミニファイ(圧縮)やフッターでのロード、依存関係の順序、多重読み込み防止といった利点があります。
「enqueue(エンキュー)」は「『キュー』(待ち行列)に並ばせる」という意味で、実際にHTMLへ出力する前に色んなスクリプトファイルをエンキューしておいて、ヘッダーやフッターでロードさせます。

無名関数

add_action( 'wp_enqueue_scripts', function() {
wp_enqueue_script( 'wspc',
   plugins_url( '/js/wspc.js', __FILE__ ),
    [ 'jquery' ] );
});

上記の例ですとPHPの無名関数を使ってロードしています。
無名関数を使う場合の利点はコードがシンプルでキレイになることです。
参考: https://torounit.com/blog/2013/05/23/1548/

無名関数を使うデメリットはenqueue_scriptsに限らず、「ロードとりやめ」が難しいことです。
add_action()したアクションはremove_action()で取りやめできますが、無名関数の場合には難しいです。
ただwp_enqueue_script()については「一旦エンキューしたファイルをデキューしたい。(やっぱロードさせない)」場合にはwp_dequeue_script()が使えます。

テーマでロードする場合

作成したテーマディレクトリにあるjsファイルをロードする方法です。

add_action( 'wp_enqueue_scripts', function() {
  wp_enqueue_script( 'my_script', 
  get_stylesheet_directory_uri().'/js/hoge.js', 
  array('jquery'), '1.0.0', true);
});

get_stylesheet_directory_uri()を使って場所を特定します。

プラグインでロードする場合

WordPressでは見た目をテーマに、機能をプラグインにという原則があります。
JavaScriptファイルがどちらに属するか迷うところもありますが、Ajax処理などを記載する場合には機能としてプラグインに分離した方が良いです。

プラグインディレクトリにおいたjsファイルを読ませる場合にはplugins_url()を使います。

add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_script( 'wspc',
        plugins_url( '/js/wspc.js', __FILE__ ), 
        [ 'jquery' ] );
    );
});

plugins_url()を使うと「ファイルが存在するか」を調べてロードしてくれます。
呼び出し方は下記のように第二引数に __FILE__ としてプラグインディレクトリにあるファイルを指定する方法が一般的です。

plugins_url( '/js/myscript.js', __FILE__ ), 

JSファイルをキャッシュさせない

第四引数にdate('U')を付けておくとブラウザがキャッシュしません。
特に開発中はオンにしておいたほうが幸せになれます。

wp_enqueue_script( 'curl_generator', get 
 _theme_file_uri('/js/curl_generator.js'),
  array('jquery'),
  date('U'),
true);

こんな感じで?の後ろに時間が付きます。

Screen Shot 2018-03-12 at 16.10.45.png

第四引数が設定されている場合にはscriptタグのクエリストリングとして出力されます。
現在時刻のUNIXタイムスタンプを付けておけば大体のブラウザはキャッシュしないです。
CDNを挟んだ時のキャッシュも回避しやすいので便利です。
開発中や修正中にキャッシュが原因で時間を取られることも多いので基本的には付けておく、運用開始後に遅いなーと思って、Google PageSpeed Insightsなどでサーバ高速化の際に見つけたら取る、って感じです。
静的キャッシュ系のプラグインを入れている場合には、JSファイルの変更日時を付けるという方法も使っています。

wp_register_script

wp_enqueue_script()でエンキューの登録を行う前に、ハンドル名を付けて登録する関数です。
あまり使わないですね。

参考: https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/wp_enqueue_script

プラグインやライブラリ系をwp_register_script()で登録しておいて、必要になった時にwp_enqueue_script()で呼ぶ、とすると見栄えが良いです。

wp_localize_script

ページごとの変数を入れる関数です。

wp_localize_script( 'wspc', 'wspc',
    array(
        'ajax_url' => admin_url( 'admin-ajax.php' ),
        'post_id'  => $post_id,
        'count_range' => array(500, 1000),
) );

上記のように書いておけば、下記のように<![CDATA[ ... ]]>でいい感じに出力してくれます。

Screen Shot 2018-03-12 at 15.18.50.png

PHPからページごとにJavaScriptの変数を埋め込む際に使います。

とはいえ、本来の使い方はは関数名にlocalizeと入っているとおり、JavaScript系のLocalize(翻訳用)用です。
ただし公式マニュアルを意訳すると変数用に使っていいよ、とのことでした。

Though localization is the primary use, it can be used to make any data available to your script that you can normally only get from the server side of WordPress.
https://codex.wordpress.org/Function_Reference/wp_localize_script

意訳後

基本的にはローカライズ用ですが、サーバからの変数取得に使われてます。

最近まで知らなかったんですがこれ便利です。

その他

この記事で書いたことの注意点などです。

バージョンなど

WordPressの推奨PHPバージョンは7.2以上です!!(強く伝えたい)

なのですが、5.2.4以上であれば動くことが保証されています。

無名関数はPHP 5.3で導入されました。
配列を[ 'foo', 'bar' ];が使えるのはPHP5.4以降です。
5.3以前はarray( 'foo', 'bar' );です。

__DIR__はPHP 5.3で導入されています。
PHP5.2以前では使えません。2018年でも5.2案件が降ってくるのですが…、慣れました ☺

そのためPHP5.2.4には無い無名関数、配列の角括弧が使えないことも多々あります。
特に配布用のテーマ、プラグインの場合には動かない原因となるので注意が必要です。

固定ページのslugと一致するjsを自動で読み込ませる

/**
 * JSファイルを読み込ませる
 */
function load_scripts() {
    if ( $pagename = get_query_var( 'pagename' ) ) {
        if ( file_exists( get_stylesheet_directory() . '/js/' . $pagename . '.js' ) ) {
            wp_enqueue_script( $pagename, get_stylesheet_directory_uri() . '/js/' . $pagename . '.js');
        }
    }
}
add_action( 'wp_enqueue_scripts', 'load_scripts' );

別の記事に書いていたものです。WordPressのシステム開発の場合、固定ページごとにJSファイルを読み込ませたい、ということ多々あります。
上記のように書いておけばslugと一致した固定ページの場合、自動的にJSファイルがロードされます。

エンジニアな自分がWordPressで何度も調べたり感心したりした事