Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've been trying to load scripts and styles for a WordPress widget with the following conditions...

  1. The scripts MUST load in the HEAD (else they break).
  2. The scripts must ONLY load when the widget actually displays (they're quite heavy).

I've done a lot of searching, and this seems to be a common (unsolved) problem...but I'm hoping someone here has successfully implemented a workaround.

This is the best I've got so far...

The following is a simple widget that prints text to the sidebar. It successfully loads jQuery conditionally (when the widget is actually displayed)...though only ever in the footer! (Note: it may also only work on WordPress 3.3, though this hack may provide backwards compatibility).

class BasicWidget extends WP_Widget
{

    function __construct() {
        parent::__construct(__CLASS__, 'BasicWidget', array(
            'classname' => __CLASS__,
            'description' => "This is a basic widget template that outputs text to the sidebar"
        ));
    }

  function form($instance) {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></label></p>
<?php
  }

  function update($new_instance, $old_instance) {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    return $instance;
  }

  function widget($args, $instance) {

    extract($args, EXTR_SKIP);

    echo $before_widget;
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);

    if (!empty($title))
      echo $before_title . $title . $after_title;;

    echo "<h1>This is a basic widget!</h1>";

    echo $after_widget;

        // if we're echoing out content, enqueue jquery.

        if (!empty($after_widget)) {
            wp_enqueue_script('jquery');
        }
    }
}
add_action( 'widgets_init', create_function('', 'return register_widget("BasicWidget");') );

It seems once WordPress starts handling widgets, it's too late to enqueue (or even deregister something enqueued earlier).

Any ideas would be much appreciated!

Mark.

share|improve this question

2 Answers 2

Wordpress as a nice function is_active_widget that you can use in your __construct and test if the widget is present in the current page and add your scripts/styles based on that ex:

function __construct() {
    parent::__construct(__CLASS__, 'BasicWidget', array(
        'classname' => __CLASS__,
        'description' => "This is a basic widget template that outputs text to the sidebar"
    ));
     if ( is_active_widget(false, false, $this->id_base) )
        add_action( 'wp_head', array(&$this, 'add_styles_and_scripts') );
}

function add_styles_and_scripts(){
    //since its wp_head you need to echo out your style link:
    echo '<link rel="stylesheet" href="http://example.com/css/style.css" type="text/css" />';
    //as for javascript it can be included using wp_enqueue_script and set the footer parameter to true:
    wp_enqueue_script( 'widget_script','http://example.com/js/script.js',array(),'',true );
}
share|improve this answer
    
Very nice man.. thanks a lot –  Sagive SEO Apr 1 '12 at 20:00
    
Thanks for your answer, Bainternet! I've just been testing your code and unfortunately, while the javascript does indeed load conditionally, it still loads in the footer...even though it's being called in wp_head. Very strange! (btw, it still does this without the "true" footer instruction). Also, echoing the stylesheet makes it load regardless of whether the widget is on the page. Any ideas? –  Mark Jeldi Apr 2 '12 at 14:03
    
wp_head is called after the head scripts are already printed out so it will only load them in the footer but you can echo it out (instead of en-queuing it) just like the stylesheet using echo '<script src="path/to/script.js"></script>'; and as for the stylesheet, its not possible that its loaded is the widgets is not active –  Bainternet Apr 2 '12 at 15:19
    
try using wp_enqueue_scripts instead of wp_head in your action. This will allow you to put the javascript in either the head or the footer. http://codex.wordpress.org/Function_Reference/wp_enqueue_script –  Nick Apr 2 '12 at 15:45
    
Thanks, Nick! I did try wp_enqueue_scripts, and while it does load the javascript in the head, it won't load conditionally. –  Mark Jeldi Apr 2 '12 at 17:36

Alternatively you could try the "Widget Logic" plug-in ... it uses conditional statements for the widget loading.

That's quite thinking the other way around - but the result should be as expected.

wp_print_scripts & wp_print_styles might be the proper hooks, just add actions to these hooks with priority 100 something - to be the very last in queue. wp_enqueue_script(), wp_enqueue_style(), wp_deregister_script(), wp_deregister_style() ...

Your issues with the code above might be lacking the priority parameter (not tested)? WP codex

share|improve this answer
    
Thanks Syslogic! I did give Widget Logic a try too, thinking I could hook into its widget_content filter. No luck unfortunately. It uses ob_start to buffer widget output so you can manipulate it before it's printed to the screen, but this is still happening too late to fire off anything in the head. Unless maybe you know of a workaround? –  Mark Jeldi Apr 4 '12 at 9:02
    
Maybe a combination of Bainternet's solution which seems just fine with widget-logic? Like this you could define which widget to load where - and also what shall been loaded. Adding own conditional statements to a theme's functions.php might help to improve further. –  syslogic Apr 20 '12 at 12:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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