WordPress.org

Make WordPress Core

Opened 22 months ago

Last modified 5 months ago

#43248 new enhancement

wp_localize_script() and ultimately print_extra_script() not using script_loader_tag filter

Reported by: csmillie Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.9.4
Component: Script Loader Keywords:
Focuses: javascript Cc:
PR Number:

Description

When you add a localized value like:

<?php
    wp_localize_script( "scripts", "localized", 'value' );

Generates

This value is added to wp_script->localized and then outputted using print_extra_script() which directly echo's the code without using the script_loader_tag filter.

I'd suggest adjusting print_extra_script() to use the script_loader_tag filter. I'm unclear if a new filter should be created but I think the existing was added to filter code like the localize additions.

I created a patch and I'm open to contributing if it's acceptable:

<?php
diff --git a/wp-includes/class.wp-scripts.php b/wp-includes/class.wp-scripts.php
index a9299f0..b770734 100644
--- a/wp-includes/class.wp-scripts.php
+++ b/wp-includes/class.wp-scripts.php
@@ -202,13 +202,25 @@ class WP_Scripts extends WP_Dependencies {
                if ( !$echo )
                        return $output;

-               echo "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
-               echo "/* <![CDATA[ */\n";
-               echo "$output\n";
-               echo "/* ]]> */\n";
-               echo "</script>\n";
+               $tag = "<script type='text/javascript'>\n"; // CDATA and type='text/javascript' is not needed for HTML 5
+               $tag .= "/* <![CDATA[ */\n";
+               $tag .= "$output\n";
+               $tag .= "/* ]]> */\n";
+               $tag .= "</script>\n";
+
+               /**
+                 * Filters the HTML script tag of an enqueued script.
+                 *
+                 * @since 4.1.0
+                 *
+                 * @param string $tag    The `<script>` tag for the enqueued script.
+                 * @param string $handle The script's registered handle.
+                 * @param string $src    The script's source URL.
+                 */
+                $tag = apply_filters( 'script_loader_tag', $tag, $handle, $output );
+
+               echo $tag;

-               return true;
        }

        /**

Change History (3)

#1 follow-up: @ocean90
22 months ago

  • Component changed from I18N to Script Loader
  • Focuses accessibility removed

Hello @csmillie, welcome to WordPress Trac!

Thanks for your request. It looks like your proposed change wouldn't be backward compatible because current plugins expect a URL for the $src argument and not raw JavaScript. Maybe it should be left empty instead. What do you think? And what's your use case for the filter at this place?

#2 in reply to: ↑ 1 @csmillie
22 months ago

Thanks for the prompt feedback.

You are correct the original filter defines the last parameter as a URL but I think using the JS output is consistent with the context and use case for the tag.

The filter allows adjustments to the tag surrounding the URL ( in the original definition ) or JS output ( as I've used ). This seems to be a natural extension to me but could be breaking as you point out.

I'm unclear if a new filter should be defined or the existing filter ( script_loader_tag ) should be re-defined/updated to note this change?

Thanks again.

Replying to ocean90:

Hello @csmillie, welcome to WordPress Trac!

Thanks for your request. It looks like your proposed change wouldn't be backward compatible because current plugins expect a URL for the $src argument and not raw JavaScript. Maybe it should be left empty instead. What do you think? And what's your use case for the filter at this place?

#3 @ShortPixel
5 months ago

I have a use case for this. We're using the filter to add this attribute:

data-cfasync="false"

to our JS so that it's not asynced out by Cloudflare. The problem is that the script is localized and it depends on the localized variables but the localized part is not caught by the filter so the main script needs to wait anyway for the async part... The solution for us would be any method to add the data-cfasync attribute also to the localized script section.

Note: See TracTickets for help on using tickets.