ショートコードが存在する場合のエンキュースクリプト/スタイル


54

プラグインで使用するためのスクリプトおよび/またはスタイルを登録/エンキューするアイデアの方法は何ですか?

最近、ユーザーのアバター/グラバターにショートコードを追加するためのシンプルなプラグインを作成しました。アバターを表示するためのさまざまなスタイルオプション(正方形、円形など)があり、CSSをショートコード自体に直接配置することにしました。

ただし、ページでショートコードが使用されるたびにcssが繰り返されるため、これは良いアプローチではないことがわかりました。私はこのサイトで他のいくつかのアプローチを見てきましたが、wp codexには独自の2つの例さえあります。

私が現在知っている方法は次のとおりです。

方法1:ショートコードに直接含める- これはプラグインで現在行っていることですが、コードを繰り返しているので良くないようです。

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );

方法2:スクリプトまたはスタイルを条件付きでキューに入れるためにクラスを使用する

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();

方法3:使用 get_shortcode_regex();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );

方法4:使用 has_shortcode();

function custom_shortcode_scripts() {
    global $post;
    if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'myshortcode') ) {
        wp_enqueue_script( 'my-script');
    }
}
add_action( 'wp_enqueue_scripts', 'custom_shortcode_scripts');

Method 4: Using has_shortcode();ショートコードの複数の使用に関係なく、投稿コンテンツにショートコードが含まれている場合、スクリプトとスタイルが一度読み込まれることを保証するため、最高だと思います。ウィジェットやサイドバーでのショートコードの使用では機能しないかもしれませんが、確かではありません。プラグイン用の場合、スクリプトをショートコードに結び付けることはお勧めしません。一部のユーザーは、目的の出力を取得するためにショートコードの代わりに関数を呼び出す場合があります。
ロバート・ヒュー14年

回答:


45

私にとってうまくいく他の方法を見つけました:

以下に、このメソッドを使用して、get_avatarをショートコードとして使用できるプラグインの例を示します。スタイルシートは、ショートコードが存在する場合にのみキューに登録されます。

使用法(idはデフォルトで現在のユーザー):

[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]

function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );

        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}

去年この質問を忘れていましたが、実際には多くの場合、この方法でこれをやり始めました。これは、方法1と2の組み合わせのようなものだ
ブライアン・ウィリス

4
このメソッドはフッターにCSSをロードしますが、これには確かに制限がありますか?
ジェイコブラクシア

1
これは絶対に正しい方法です。このメソッドは、wp_enqueue_scriptsフックが既に発生しているときにスクリプトまたはスタイルシートを条件付きでロードする必要があるときにいつでも使用します。(ショートコードはフックのthe_content一部である間に解析されthe_postます。
つまり、

26

回答を始める前に、このトピックに関してcssとjsは同じではないと言わなければなりません。

理由は簡単です:ページの本文にフッターでjsを追加するのが一般的かつ有効な方法ですが、CSSを<head>ページのセクションに配置する必要があります:大半のブラウザがページ内でCSSを適切にレンダリングできる場合でもbody、これは有効なHTMLコードではありません。

ショートコードがレンダリングされる場合、<head>セクションはすでに印刷されています。つまり、フッターに問題なくjsを追加できますが、ショートコードをレンダリングする前に cssを追加する必要があります。

スクリプト

ショートコードにjsのみが必要な場合は、ラッキーでありwp_enqueue_script、ショートコードコールバックの本文で使用できます。

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}

そうすることで、ページでショートコードが複数回使用されている場合でも、スクリプトはフッターに1回だけ追加されます。

スタイル

コードにスタイルが必要な場合は、ショートコードが実際にレンダリングされるに行動する必要があります。

これを行うにはさまざまな方法があります。

  1. 現在のクエリのすべての投稿を見て、必要に応じてショートコードスタイルを追加します。これは、OPのメソッド#3と#4の両方で行うことです。実際、2つのメソッドはどちらも同じことを行いますがhas_shortcode、WP 3.6で追加されましたがget_shortcode_regex、バージョン2.5以降で使用できるget_shortcode_regexため、プラグインを古いバージョンと互換性があるようにする場合にのみ使用してください。

  2. すべてのページに常にショートコードスタイルを追加する

課題

#1の問題はパフォーマンスです。正規表現は非常に遅い操作であり、すべての投稿のループで正規表現を起動すると、一貫してページが遅くなる場合があります。さらに、アーカイブでは抜粋投稿のみを表示し、ショートコードを含む完全なコンテンツを単一のビューでのみ表示することは、テーマでは非常に一般的なタスクです。その場合、アーカイブが表示されると、プラグインは使用されないスタイルを追加することを目的として、ループ内で正規表現のマッチングを開始します。

#2の問題はパフォーマンスです。すべてのページにスタイルを追加すると、不要な場合でも、すべてのページに追加のHTTPリクエストが追加されます。サーバー側のページ生成時間が影響を受けていなくても、合計ページレンダリング時間はすべてのサイトページに影響します。

それでは、プラグイン開発者は何をすべきでしょうか?

行うべき最善の方法は、プラグインにオプションページを追加することです。ユーザーは、ショートコードを単一ビューのみで処理するか、アーカイブで処理するかを選択できます。どちらの場合も、ショートポストを有効にする投稿タイプを選択する別のオプションを提供することをお勧めします。

そのようにして"template_redirect"、現在のクエリが要件を満たしているかどうかを確認するためにフックし、その場合スタイルを追加することができます。

ユーザーが単一の投稿ビューでのみショートコードを使用することを選択した場合、投稿にショートコードがあるかどうかを確認することをお勧めします。一度正規表現が1つだけ必要な場合は、ページをそれほど遅くしないでください。

ユーザーがさえアーカイブにショートコードを使用することを選択した場合は、投稿数があるならば、私はすべての記事のために正規表現を実行するために避けるだろう高いとスタイルだけであれば、クエリの適合要件をエンキュー。

この点で「高」と見なすものは、いくつかのパフォーマンステストを使用するか、別の方法として別のオプションを追加してユーザーに選択肢を与えることです。


2
ここで<style>は、ドキュメント本文のタグがW3C仕様に従って有効になっていることに注意してください。w3.org/TR/html52/document-metadata.html#the-style-element
Isaac

5

私のプラグインでは、ユーザーがポストメタデータに格納されたショートコードを持つテーマビルダーを持っていることがあります。プラグインショートコードが現在の投稿または投稿メタデータに存在するかどうかを検出するために使用しているものは次のとおりです。

function abcd_load_my_shorcode_resources() {
       global $post, $wpdb;

       // determine whether this page contains "my_shortcode" shortcode
       $shortcode_found = false;
       if ( has_shortcode($post->post_content, 'my_shortcode') ) {
          $shortcode_found = true;
       } else if ( isset($post->ID) ) {
          $result = $wpdb->get_var( $wpdb->prepare(
            "SELECT count(*) FROM $wpdb->postmeta " .
            "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'", $post->ID ) );
          $shortcode_found = ! empty( $result );
       }

       if ( $shortcode_found ) {
          wp_enqueue_script(...);
          wp_enqueue_style(...);
       }
}
add_action( 'wp_enqueue_scripts', 'abcd_load_my_shorcode_resources' );

2

私はそうします:

class My_Shortcode {

    function __construct() {
        do_action('my_start_shortcode'); // call
....

他の関数(または他のプラグイン)のフックをキャッチします。

function wpse_3232_load_script(){
    wp_enqueue_script('js-myjs');
}
add_action('my_start_shortcode','wpse_3232_load_script',10);

1

テキストウィジェットにショートコードが存在する場合、自分のプラグインを見つけました。

function check_shortcode($text) {

  $pattern = get_shortcode_regex();

   if (   preg_match_all( '/'. $pattern .'/s', $text, $matches )
        && array_key_exists( 2, $matches )
        && in_array( 'myshortcode', $matches[2] ) )
    {
        // myshortcode is being used

        // enque my css and js
        /****** Enqueu RFNB  ******/
        wp_enqueue_style('css-mycss');
        wp_enqueue_script('js-myjs');

        // OPTIONAL ALLOW SHORTCODE TO WORK IN TEXT WIDGET
        add_filter( 'widget_text', 'shortcode_unautop');
        add_filter( 'widget_text', 'do_shortcode'); 

    }

  return $text;

}
add_filter('widget_text', 'check_shortcode');

1

WordPressには、ステータスを表示する特定のショートコードに基づいて何かを行うための組み込み関数があります。関数名はhas_shortcode()です。次のコードを使用して、スタイルとスクリプトをエンキューできます。

ここではis_a( $post, 'WP_Post' )$postオブジェクトがWP_Postクラスのものであるかどうかをチェックするために使用$post->post_contentし、投稿コンテンツをチェックするために使用しました。

if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'shortcode_tag') ) {
    wp_enqueue_style( 'handle', get_template_directory_uri() . '/your_file_filename.css' );
}

0

has_shortcode()の Wordpressページのサンプルコードとzndenckaの回答を組み合わせて作成しました。has_shortcode関数がWordpress 3.6に追加されたことに気付きました。そのため、最初に関数が存在するかどうかを確認します。ただし、wordpressの統計によると、wordpress 3.6未満のユーザーはもういないため、このチェックは少し時代遅れかもしれません

// This makes sure the styling is already enqueued in the header, so before the shortcode loads in the page/post
function enqueue_shortcode_header_script() {
    global $post;
    if ( function_exists( 'has_shortcode' ) ){  // is added in wordpress 3.6
        // Source: https://codex.wordpress.org/Function_Reference/has_shortcode
        if( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'my_shortcode') ) {
            wp_enqueue_style( 'shortcode-css' );
        }
    }
    else if ( isset($post->ID) ) { // Small percentage wordpress users are below 3.6 https://wordpress.org/about/stats/
        global $wpdb;
        $result = $wpdb->get_var(
          $wpdb->prepare(
              "SELECT count(*) FROM $wpdb->postmeta " .
              "WHERE post_id = %d and meta_value LIKE '%%my_shortcode%%'",
               $post->ID )
        );
        if (!empty( $result )) { wp_enqueue_style( 'shortcode-css' ); }
    }
}
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_header_script');

0

過度に精巧な関数を使用せずに、CSSファイルとJSファイルをショートコード経由で条件付きで実際に読み込むことができます。

最初に、CSS / JSファイルをすべて以前に登録したと仮定します(おそらく実行されたときwp_enqueue_scripts

function prep_css_and_js() {
     wp_register_style('my-css', $_css_url);
     wp_register_script('my-js', $_js_url);
}
add_action( 'wp_enqueue_scripts', 'prep_css_and_js', 5 );

次に、ショートコード関数を調べてみましょう。

function my_shortcode_func( $atts, $content = null ) {
  if( ! wp_style_is( "my-css", $list = 'enqueued' ) ) { wp_enqueue_style('my-css'); }
  if( ! wp_script_is( "my-js", $list = 'enqueued' ) ) { wp_enqueue_script('my-js'); }
  ...
}

シンプル。できた Ergo:css / jsファイルを「条件付きで」読み込むことができます([ショートコード]が実行されている場合のみ)。

次のイデオロギーを考えてみましょう。

  • 特定のCSS / JSファイルをロードしたい(ただし、ショートコードがトリガーされた場合のみ)
  • おそらく、これらのファイルをすべてのページにロードしたくない、またはページ/投稿にショートコードが使用されていない場合はまったくロードしたくないでしょう。(軽量)
  • これを実現するには、ショートコードを呼び出す前とエンキューする前に、WPがすべてのcss / jsファイルを登録するようにします。
  • IE:私のprep_css_and_js()機能中に特定のフォルダーにあるすべての.css / .jsファイルをロードする可能性があります...

WPはそれらを登録されたスクリプトと見なすようになったので、状況の真偽に基づいて条件付きで呼び出すことができます。 my_shortcode_func()

利点:(MySQL、高度な機能、フィルターは不要)

  • これは「WPオーソディックス」、エレガントで高速なロード、簡単でシンプルな
  • コンパイラ/ミニファイヤがそのようなスクリプトを検出できるようにします
  • WP関数(wp_register_style / wp_register_script)を使用します
  • さまざまな理由でこれらのスクリプトの登録を解除する可能性のある、より多くのテーマ/プラグインと互換性があります。
  • 複数回トリガーしません
  • 処理やコードはほとんど関与していません

参照:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.