1

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

I'm adding a public shortcode function for wich I will need some resources (js and css), I want to enqueue scripts (that go in the footer) only when necessary, so I need to enqueue scripts just before the return of the shortcode.

Thanks to Fayaz answer I solved the main problem, but I still got a small one: I can't pass $this->plugin_name to shortcode function, variable I need to correctly name resources in the wp_enqueue_script function.

As the Boilerplate provide just add_action hooks in define_public_hooks function, I did use that, and nested inside it the add_shortcode hook, like this:

class My_Plugin {
   $plugin_public = new My_Plugin_Public( $this->get_plugin_name(), $this->get_version() );

   $this->loader->add_action( 'init', $plugin_public, 'my_plugin_ajax_register_shortcode' );

}

then in my-plugin-public.php file:

class My_Plugin_Public {

  public function __construct( $plugin_name, $version ) {

        $this->plugin_name = $plugin_name;
        $this->version = $version;

    }

  public function my_plugin_ajax_register_shortcode(){


     function the_actual_shortcode($atts){

        $content = 'shortcode content';

        wp_enqueue_script( $this->plugin_name.'_google_maps_api' ); // we don't know what $this->plugin_name is!

        return $content;    
     }
     add_shortcode('my_shortcode', the_actual_shortcode);
 }

}

As you can imagine, the the_actual_shortcode function, ignores $this->plugin_name, how can I pass it?

1 Answer 1

1

There are multiple ways to accomplish this. I'm showing you a way that will not fundamentally change how you are doing it:

First in My_Plugin class:

class My_Plugin {
    // ...
    private function define_public_hooks() {
        $plugin_public = new My_Plugin_Public( $this->get_plugin_name(), $this->get_version() );
        $this->loader->add_action( 'init', $plugin_public, 'init' );
        // ...
    }
    // ...
}

Then in My_Plugin_Public class, create a new method named init. Here you'll do things that you want once WordPress init action hook is triggered. So adding shortcode will go into this init method:

class My_Plugin_Public {

    public function __construct( $plugin_name, $version ) {

        $this->plugin_name = $plugin_name;
        $this->version = $version;

    }

    public function init() {
        add_shortcode( 'my_shortcode', array( $this, 'my_plugin_ajax_register_shortcode' ) );
    }

    public function my_plugin_ajax_register_shortcode( $atts ) {
        $content = 'shortcode content';
        wp_enqueue_script( $this->plugin_name . '_google_maps_api' );
        return $content;
    }
}

So, basically instead of creating an inner function within the class method my_plugin_ajax_register_shortcode, we are utilizing another method named init within the class. Now we'll be able to access $this->plugin_name inside the shortcode handler function, because now it's within the scope of our My_Plugin_Public class.

2
  • Tnx Fayaz, what about putting add_shortcode inside __construct() without creating init()? I tried and works. Are there some issues?
    – bluantinoo
    Commented Mar 16, 2017 at 13:23
  • There are many ways you can do it. However, some WordPress core features are available only after the init hook is fired. So make sure you have a clear understanding of WordPress core loading order. Answers here may help.
    – Fayaz
    Commented Mar 16, 2017 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.