え?このやり方間違ってたの? WordPressでJavaScriptやCSSを正しく読み込む方法

2016/05/11

Younes Rafie

8

Articles in this issue reproduced from SitePoint
Copyright © 2016, All rights reserved. SitePoint Pty Ltd. www.sitepoint.com. Translation copyright © 2016, KADOKAWA ASCII Research Laboratories, Inc. Japanese syndication rights arranged with SitePoint Pty Ltd, Collingwood, Victoria,Australia through Tuttle-Mori Agency, Inc., Tokyo

WordPressがなぜか遅い。キャッシュも使っているのに……そんなときは、あなたの作ったテーマのJavaScriptやCSSの読み込み方が間違っているのかもしれません。おすすめの方法はこちら。

WordPressのプラグインやテーマの開発にしばらく携わると、テーマのパフォーマンスや発生が予想される課題の解決方法を考えるようになります。課題の1つとして、スクリプトやスタイルのエンキューがあります。この記事ではスクリプトのエンキューの基本、実用的でベストな方法を紹介します。こちら記事ではWordPress初心者向けに解説していますのでチェックしてみてください。

01

スクリプトやスタイルのエンキュー

WebページにCSSやJavaScriptを導入する場合、HTMLファイル内に加えるか、ダイレクトURLを使ってファイルを指定するかのどちらかを選びます。

// ...
<script type="text/javascript">
    // some JS code
</script>

<style type="text/css">
    // some CSS code
</style>
//...

<script type="text/javascript" src="<?= plugins_url('assets/js/main.js') ?>"></script>

しかし、WordPressのスクリプトを加えるときにはおすすめできません。この方法は、プラグインのキャッシュを使ってもサイトパフォーマンス向上のための設定の最適化や保存はされないためです。admin_enqueue_scriptsフックを使う必要があるのです。

add_action( 'admin_enqueue_scripts', function($hook) {
    $pluginPrefix = "my-prefix";
    wp_enqueue_script( "{$pluginPrefix}main-js", plugins_url('assets/js/main.js'), ['jquery'] );
} );

wp_enqueue_script関数の第1のパラメーターは、スクリプトハンドラー名です。コンフリクトを防ぎスクリプトが常にロードされるよう確認するためにも、ハンドラーを先づけしなければなりません。

現状の方法では完壁ではなく、スクリプトがすべてのバックエンドページに含まれてしまっています。コールバック関数に渡されている$hook変数を使い、特定ページの検証をします。

add_action( 'admin_enqueue_scripts', function($hook) {
    if ( !in_array($hook, array("options-general.php", "post-new.php")) )
        return;

    $pluginPrefix = "my-prefix";
    wp_enqueue_script( "{$pluginPrefix}main-js", plugins_url('assets/js/main.js'), ['jquery'] );
} );

これで、スクリプトは設定したページと新しい投稿ページのみに含まれるようになります。あとはユーザーが新しいページを作成するときに、スタイルを含めるだけで完了です。

add_action( 'admin_enqueue_scripts', function($hook) {
    if ( $hook == "post-new.php" && isset($_GET['post_type']) && $_GET['post_type'] == "page" )
    {
        $pluginPrefix = "my-prefix";
        wp_enqueue_script( "{$pluginPrefix}main-js", plugins_url('assets/js/main.js'), ['jquery'] );
    }
} );

不要なスクリプトを削除する

スクリプトのエンキューについて、必要な場合を除いてきちんと考えている開発者は少なく、そのために予想外のエラーやよく分からないスタイリングの問題が発生してしまいます。スクリプトがエラーやコンフリクトの原因の場合、他のスクリプトを追加する前に取り除くことができます。デバッグモードを使うと便利です。

add_action( 'admin_enqueue_scripts', function($hook) {
    $unautorized_styles = [
        'script1',
        'another-script'
    ];

    foreach ( $unautorized_styles as $handle )
    {
        wp_deregister_style( $handle );
    }

    // enqueue my scripts
} );

ショートコードでの作業

多くのプラグインやテーマにはWebサイトと相互作用するショートコードセットがあり、ページ内にスクリプトを導入しなければならなない場合があります。しかし、バックエンドページからテストをしていると、フロントエンドページのテストはできません。

それでもフロントエンドページのテストをするには、the_contentでコールバックを登録し、その中にショートコードが含まれているか確かめます。含まれていればスクリプトのエンキューができます。ショートコードが含まれていなければ作業をする必要はありません。

add_filter( 'the_content', function($content) {
    if ( has_shortcode($content, "hello-shortcode") )
    {
        $pluginPrefix = "my-prefix";
        wp_enqueue_script( "{$pluginPrefix}main-js", plugins_url('assets/js/hello-shortcode.js') );
    }
});

このコードはうまくできていて、作成したショートコードを含む投稿のみをエンキューします。しかし、この方法は負荷の大きいWebサイトで使うと重大なパフォーマンスの問題を引き起こします。問題を回避するために使える、もっとハイレベルな方法がこちらです。

クラスの読み込みにComposerを使ってないのなら、是非、今からでも使ってみてください。私たちが開発したプラグインcomposer.jsonを使うとこのようになります。

// composer.json
{
    "name": "Demo plugin",
    "description": "",
    "authors": [
        {
            "name": "Author name",
            "email": "author.name@example.com"
        }
    ],
    "autoload": {
        "psr-4": {
            "ESP\\": "src/"
        }
    }
}

src/shortcodes/HelloShortcode.phpクラス内にショートコードの定義が含まれています。

// src/shortcodes/HelloShortcode.php

namespace ESP\Shortcodes;

class HelloShortcode
{
    static $loaded;

    public $name;

    public function __construct()
    {
        $this->name = "hello-shortcode";
    }

    public function run()
    {
        static::$loaded = true;

        return "Hello shortcode!";
    }

    public function enqueueScripts()
    {
        if ( static::$loaded == false )
            return;

        $pluginPrefix = "my-prefix";
        wp_enqueue_script( "{$pluginPrefix}main-js", plugins_url('assets/js/hello-shortcode.js') );
    }
}

runメソッドではHTMLマークアップがショートコードに返され、ショートコードが使用されているときloaded静的属性をtrueにします。

enqueueScriptsメソッドでは、プラグインがロードされているときにスタイルをエンキューします。残った部分はショートコードを登録し、投稿コンテンツ内で認識されます。

// plugin-file.php

require_once __DIR__."/vendor/autoload.php";

$shortcodes = [
    'ESP\\Shortcodes\\HelloShortcode'
];

foreach ($shortcodes as $shortcode) {
    $shortcode = new $shortcode;
    add_shortcode($shortcode->name, [ $shortcode, 'run' ]);
}

add_action('wp_footer', function() use($shortcodes) {
    foreach ($shortcodes as $shortcode) {
        (new $shortcode)->enqueueScripts();
    }
});

このコードがメインのプラグインに入らないようにできますが、ここではコード類をシンプルで読みやすくしておきます。

$shortcodes変数には使用可能なショートコードの一覧が含まれています。最初のループでショートコードを登録し、runメソッドをハンドラーにします。次にwp_footerフックを使い、bodyタグを閉じる前にショートコードスクリプトをエンキューします。

これで、ショートコードを含む新しいページの作成や、スクリプトが正常にロードされているかの確認ができます。

まとめ

この記事はプラグインやテーマスクリプトのエンキュー方法、Webサイトの全ページにプラグインやテーマスクリプトがロードされるのを防ぐ方法のまとめとして作成しました。

(原文:Enqueuing Scripts and Styles in WordPress

[翻訳:加藤由佳]
[編集:Livit

Copyright © 2016, Younes Rafie All Rights Reserved.

Younes Rafie

Younes Rafie

モロッコ出身、フリーランスのWeb開発者、技術系ライター・ブロガーとして活躍中。JAVA、J2EE、JavaScriptとの共同作業経験があり、専門はPHP言語。詳しくは彼のWebサイトを。

Loading...