How to enqueue script if widget is displayed on page?

I created a widget that uses a jquery plugin, and I used is_active_widget to enqueue the script, it’s working fine but it’s also including the script even on pages that doesn’t show this widget.
so is there a way to only enqueue the script if this widget is showing ?

thanks in advance.

Related posts

Leave a Reply

4 comments

  1. You should be able to call wp_enqueue_script() as part of your Widget output.

    Edit

    Quick-and-dirty, using the bare-bones Widgets API class example:

    <?php
    class wpse48337_Widget extends WP_Widget {
    
        public function __construct() {
            // widget actual processes
        }
    
        public function form( $instance ) {
            // outputs the options form on admin
        }
    
        public function update( $new_instance, $old_instance ) {
            // processes widget options to be saved
        }
    
        public function widget( $args, $instance ) {
            // outputs the content of the widget
        }
    
    }
    register_widget( 'wpse48337_Widget' );
    ?>
    

    Add your wp_enqueue_script() call inline, within your Widget’s output – i.e. within the public function widget():

    <?php    
        public function widget( $args, $instance ) {
            // outputs the content of the widget
    
        // Enqueue a script needed for
        // the Widget's output
        wp_enqueue_script( 'jquery-pluginname', $path, $deps );
    
        // Rest of widget output goes here...
        }
    ?>
    
  2. If the script needs to go in the <head> section:

    class Your_Widget extends WP_Widget{
    
      protected static $did_script = false;
    
      function __construct(){
    
        // parent::__construct() ...
    
        add_action('wp_enqueue_scripts', array($this, 'scripts'));
    
      }
    
      function scripts(){
    
        if(!self::$did_script && is_active_widget(false, false, $this->id_base, true)){
          wp_enqueue_script('your-script');
          self::$did_script = true;
        }           
    
      }
    
    
    }
    

    Otherwise, Chip Bennett’s solution will work for queuing it in the footer.

    The $did_script static variable is not required, I used it just to avoid further unnecessary calls to wp_enqueue_script if there are multiple widget instances on the page…

  3. Pierre,

    The way I handle this is with wp_enqueue_script and wp_dequeue_script, and use a instance variable $is_active in the Your_Widget class

    So do the wp_enqueue_script based on is_active_widget which enqueues the script on all pages but with the footer parameter set to true. Note the dequeue is run at a priority to make sure it runs before the scripts are output.

    function enqueue_scripts() {
      if ( is_active_widget( false, $this->id, $this->id_base, true ) ) {
        wp_enqueue_script( 'your-script-handle', 'your-script-url', array(), '1.0', true );
        add_action( 'wp_footer', array($this,'dequeue_redundant_scripts'), 1 );
      }
    

    }

    Then in the widget function indicate if the widget is active on that page

    function widget( $args, $instance ) {
        // outputs the content of the widget
        $this->is_active = true;  
    }
    

    Then in the footer dequeue the script if the widget is not active on that page

    function dequeue_redundant_scripts() {
        if (! $this->is_active) {
            wp_dequeue_script('your-script-handle');
        }
    }
    

    This approach of enqueue then dequeueing if unused also works well for plugins that define shortcodes which require scripts

  4. I considered ‘wp_footer’ hook because this hook is executed at footer,and is probably the best way to add scripts only where the widget is used.

    class Your_Widget extends WP_Widget{
    
        function widget( $args, $instance ) {
    
             add_action('wp_footer',array($this,'front_end_scripts'));
    
        }
    
        function front_end_scripts(){
           ?><script type="text/javascript">
              console.log('this works!');
            /*
              Or if you need external scripts then you may use 
              $.getScript([your-script-url] );
            */
            </script> <?php
        }
    
    
    
    }