Enqueue script only when shortcode is used, with WP Plugin Boilerplate

The question:

I’m building a plugin using the WordPress Plugin Boilerplate by DevinVinson.

Everything works fine, except one thing:

I’m trying to enqueue scripts and css only when a shortcode is present in the page.

In define_public_hooks function, I added a call to the loader to register scripts instead of enqueuing them:

private function define_public_hooks() {
    // ...
    $this->loader->add_action( 'wp_register_script', $plugin_public, 'register_styles' );
    $this->loader->add_action( 'wp_register_script', $plugin_public, 'register_scripts' );
    // ...

Then in class-my-plugin-public.php file I created two public functions register_styles() and register_scripts(). Inside these functions, I just register scripts and styles, instead of enqueuing them. It’s something basic, like this:

public function register_scripts() {    
    wp_register_script( $this->plugin_name . '_google_maps_api', '//maps.googleapis.com/maps/api/js?key='. $gmap_key .'&v=3&libraries=places', array( 'jquery' ), '3', true );

Then I would like to enqueue them in the shortcode return function, but they do not get registered at all.

I checked with wp_script_is( $this->plugin_name . '_google_maps_api', 'registered' ), and it returns false.

If I make the very same stuff, but with enqueue instead of register everything works fine.

Any idea why?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Why it’s not working:

You need to use the wp_enqueue_scripts action hook. You’ve used wp_register_script as an action hook, however, there is no action hook named wp_register_script in WordPress core.

If this was just a silly mistake, then you already have the answer. Read on if you need more information regarding the topic:

Attaching a callback function to wp_enqueue_scripts action hook doesn’t mean your scripts and styles will be enqueued, it simply means when you want to execute that callback function.

The original registering and enqueuing is done by functions such as: wp_register_script(), wp_register_style, wp_enqueue_script(), wp_enqueue_style() etc., not by any hook.

Note the difference between the role of functions and hooks:

  • A function executes some CODE to accomplish predefined tasks when called.

    Example: these all are WordPress core functions: wp_register_script(), wp_register_style, wp_enqueue_script(), wp_enqueue_style().

  • A hook only attaches a callable function (to be executed later) at a predefined point of CODE execution.

    Example: this is a WordPress core (action) hook: wp_enqueue_scripts – notice the s (plural) at the end.

    Double check: wp_enqueue_script() is a function and wp_enqueue_scripts is an action hook.

The correct CODE:

So your corrected CODE should be like:

private function define_public_hooks() {
    // ...
    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'register_styles' );
    $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'register_scripts' );
    // ...


public function register_scripts() {
    wp_register_script( $this->plugin_name . '_google_maps_api', '//maps.googleapis.com/maps/api/js?key='. $gmap_key.'&v=3&libraries=places', array( 'jquery' ), '3', true );

After that, you enqueue the script (& style) from within you shortcode handler function:

public function your_shortcode_handler( $atts ) {
    // shortcode related CODE
    wp_enqueue_script( $this->plugin_name . '_google_maps_api' );
    // more shortcode related CODE

With this CODE, your scripts / styles enqueued from your_shortcode_handler function will only be added to your site when there is a shortcode in that particular URL.

Further Reading:

This answer has an interesting discussion on enqueuing scripts & styles only when shortcode is present.

Method 2

So the problem is that the first argument to the add_action call needs to be a WordPress action name… So “wp_register_script”, not being a WP action, is never called.

I’d suggest all you need to do, really, is add your registering calls to your plugin’s enqueue_scripts function – no need to fuss with the define_public_hooks, or create a new register_scripts function. Simply go with the existing enqueue_scripts function, but add your registrations there:

public function enqueue_scripts() {
    wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/plugin-name-public.js', array( 'jquery' ), $this->version, false );

    // NOTICE this is a *registration* only:
    wp_register_script( $this->plugin_name.'_google_maps_api', '//maps.googleapis.com/maps/api/js?key='. $gmap_key.'&v=3&libraries=places', array( 'jquery' ), '3', true ); 

Then when your short code, your script should be registered, ready to be enqueued.

Hope this helps!

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment