最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

plugins - Add extra parameter in <script> tag using script_loader_tag

programmeradmin1浏览0评论

I am using this code in my plugin to enqueue script:

wp_enqueue_script( 'wpfrank-ptbw-pinit-js', PTBW_PLUGIN_URL . 'assets/js/pinit.js', array('jquery'), '', true );

The wp_enqueue_script function making a default <script> tag output like this:

<script type='text/javascript' src='http://localhost/development/wp-content/plugins/pin-it-button-pinterest-widgets/assets/js/pinit.js'></script>

Want to add some extra parameter into the script tags like:

<script async defer data-pin-hover="true" src="http://localhost/development/wp-content/plugins/pin-it-button-pinterest-widgets/assets/js/pinit.js"></script>
  1. asysnc
  2. defer
  3. data-pinhover="true"

How do I achieve that using wp_enqueue_script?

Are there any hook or action to pass extra parameters?

Any help really appreciated.

I am using this code in my plugin to enqueue script:

wp_enqueue_script( 'wpfrank-ptbw-pinit-js', PTBW_PLUGIN_URL . 'assets/js/pinit.js', array('jquery'), '', true );

The wp_enqueue_script function making a default <script> tag output like this:

<script type='text/javascript' src='http://localhost/development/wp-content/plugins/pin-it-button-pinterest-widgets/assets/js/pinit.js'></script>

Want to add some extra parameter into the script tags like:

<script async defer data-pin-hover="true" src="http://localhost/development/wp-content/plugins/pin-it-button-pinterest-widgets/assets/js/pinit.js"></script>
  1. asysnc
  2. defer
  3. data-pinhover="true"

How do I achieve that using wp_enqueue_script?

Are there any hook or action to pass extra parameters?

Any help really appreciated.

Share Improve this question edited Feb 27, 2020 at 13:19 Frank asked Feb 27, 2020 at 10:23 FrankFrank 1763 silver badges13 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 7

You can use script_loader_tag filter to fulfill your requirement. add below code in your active theme's functions.php file. it will add extra parameter in your script tag.

function add_attribute_to_script_tag($tag, $handle) {
   # add script handles to the array below
   $scripts_to_defer = array('wpfrank-ptbw-pinit-js');

   foreach($scripts_to_defer as $defer_script) {
      if ($defer_script === $handle) {
         return str_replace(' src', '  async defer data-pin-hover="true" src', $tag);
      }
   }
   return $tag;
}
add_filter('script_loader_tag', 'add_attribute_to_script_tag', 10, 2);

I revised the answer once more because I recently noticed how the Twenty Twenty developers use the script_loader_tag hook to add async and defer to the <script> tag for the theme scripts.

  1. In twentytwenty_theme_support() in functions.php, lines #139 & #140:

    $loader = new TwentyTwenty_Script_Loader();
    add_filter( 'script_loader_tag', array( $loader, 'filter_script_loader_tag' ), 10, 2 );
    
  2. In twentytwenty_register_scripts() in functions.php, lines #208 & #209:

    wp_enqueue_script( 'twentytwenty-js', get_template_directory_uri() . '/assets/js/index.js', array(), $theme_version, false );
    wp_script_add_data( 'twentytwenty-js', 'async', true );
    
  3. And in the TwentyTwenty_Script_Loader class:

    public function filter_script_loader_tag( $tag, $handle ) {
        foreach ( [ 'async', 'defer' ] as $attr ) {
            if ( ! wp_scripts()->get_data( $handle, $attr ) ) {
                continue;
            }
            ...
        }
        return $tag;
    }
    

So what I'm trying to say/suggest, is that you should probably better off use the wp_script_add_data() to add/register the custom HTML attributes (e.g. async) for your scripts and use the wp_scripts()->get_data() to check if the <script> tag should be added with the custom HTML attributes, without having to manually specify the handle (e.g. your wpfrank-ptbw-pinit-js).

And here's an example based on the above approach, where I'm registering a list of custom or extra HTML attributes for a script using wp_script_add_data( '<handle>', 'html_attrs', [ list here ] ). Additionally, I'm using PHP's DOMDocument for a more precise result, although str_replace() or preg_replace() would also do.

add_action( 'wp_enqueue_scripts', 'my_register_scripts' );
function my_register_scripts() {
    wp_enqueue_script( 'wpfrank-ptbw-pinit-js', PTBW_PLUGIN_URL . 'assets/js/pinit.js', array( 'jquery' ), '', true );
    wp_script_add_data( 'wpfrank-ptbw-pinit-js', 'html_attrs', [
        'async'          => 'async',
        'defer'          => true,
        'data-pin-hover' => 'true',
    ] );
}

add_filter( 'script_loader_tag', 'my_filter_script_loader_tag', 10, 2 );
function my_filter_script_loader_tag( $tag, $handle ) {
    $attrs = wp_scripts()->get_data( $handle, 'html_attrs' );

    // Bail if the script doesn't have any registered custom HTML attrs.
    if ( empty( $attrs ) || ! is_array( $attrs ) ) {
        return $tag;
    }

    $dom = new DOMDocument;

    //$tag = mb_convert_encoding( $tag, 'HTML-ENTITIES', 'UTF-8' );
    $dom->loadHTML( $tag, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );

    $node = $dom->getElementsByTagName( 'script' )[0];
    foreach ( $attrs as $key => $value ) {
        $node->setAttribute( $key, $value );
    }

    return $dom->saveHTML();
}

In addition of Chetan Vaghela answer, you can use a switch statement, only for performance and customization related purposes:

function add_attribute_to_script_tag($tag, $handle) {

    switch($handle){
        case 'wpfrank-ptbw-pinit-js': return str_replace(' src', ' async defer data-pin-hover="true" src', $tag);
        default: return $tag;
    }
}
add_filter('script_loader_tag', 'add_attribute_to_script_tag', 10, 2);
发布评论

评论列表(0)

  1. 暂无评论