Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Load Scripts Only If a Specific Widget is Active WordPress

Hi everyone!

I'm trying to load scripts for a widget I've written after checking if the widget is in use. The widget works perfectly fine if I'm calling the scripts directly like this:


function jg_register_js() {
if (!is_admin()) {

wp_enqueue_script('map-js', 'http://maps.google.com/maps?file=api&v=2&key=' . of_get_option('map_api') .'');
wp_enqueue_script('map', get_template_directory_uri() . '/js/jquery.gmap-1.1.0-min.js', 'jquery');

}
}
add_action('init', 'jg_register_js');


But I don't want those scripts in the header if the widget isn't being used so I'm trying to do something like this:


function jg_gmap_script() {
if ( is_active_widget('jg_Map') ) {

wp_enqueue_script('map-js', 'http://maps.google.com/maps?file=api&v=2&key=' . of_get_option('map_api') .'');
wp_enqueue_script('map', get_template_directory_uri() . '/js/jquery.gmap-1.1.0-min.js', 'jquery');

}

}
add_action('template_redirect', 'jg_gmap_script');



I'm not sure what I could be missing here. I double checked the classname of the widget so that's correct ('jg_Map').

Hopefully it's something really simple that I can blame on working in front of the computer too long. ;)

Answers (5)

2011-06-24

Andrzej answers:

Calling it at 'init' might be too early. Try hooking into 'wp_enqueue_scripts' ?


beowulf comments:

Sorry, yes. I was originally using 'template_redirect' (so that it only loads on the front end) but was trying every darn thing to get it to work and 'init' was left over from when I was modifying it.

So my function looks like this:



function jg_gmap_script() {

if ( is_active_widget('jg_Map') ) {

wp_enqueue_script('map-js', 'http://maps.google.com/maps?file=api&v=2&key=' . of_get_option('map_api') .'');

wp_enqueue_script('map', get_template_directory_uri() . '/js/jquery.gmap-1.1.0-min.js', 'jquery');


}

}

add_action('template_redirect', 'jg_gmap_script');

2011-06-24

Linda answers:

Hi, how about trying this...


function jg_gmap_script() {
if ( is_active_widget('jg_Map') )
return;
wp_enqueue_script( 'map-js', 'http://maps.google.com/maps?file=api&v=2&key=' . of_get_option('map_api') .'');
wp_enqueue_script('map', get_template_directory_uri() . '/js/jquery.gmap-1.1.0-min.js', 'jquery');
}
add_action( 'template_redirect', 'jg_gmap_script' );


-Linda


beowulf comments:

Your function partially works, Linda.

With my original function, it wasn't loading the scripts at all but with yours, it's loading the scripts all the time (with or without the widget active).


Linda comments:

Hi, do you know the id of your widget?


beowulf comments:

Yes. It's 'jg_Map'.



class jg_Map extends WP_Widget {
function jg_Map() {
$widget_ops = array('classname' => 'jg_Map', 'description' => 'Display map' );
$this->WP_Widget('jg_Map', 'Map Widget', $widget_ops);
}


Linda comments:

The WordPress codex says you need

<?php is_active_widget( $callback, $widget_id, $id_base, $skip_inactive ); ?>

So maybe by using the below put instead put the widget id it might work.


function jg_gmap_script() {

if ( is_active_widget(false,'PUT WIDGET ID') )

return;

wp_enqueue_script( 'map-js', 'http://maps.google.com/maps?file=api&amp;v=2&amp;key=' . of_get_option('map_api') .'');

wp_enqueue_script('map', get_template_directory_uri() . '/js/jquery.gmap-1.1.0-min.js', 'jquery');

}

add_action( 'template_redirect', 'jg_gmap_script' );


Can you add the

'id' => 'jg_Map' to the class function?


beowulf comments:

I tried that new function and it's giving me the same results; always returning the scripts in the head regardless if the widget is being used or not. I feel like there's something else going on here but I just can't put my finger on it.

There's one other alternative I can think of. This widget also relies on user input of an API key in the theme's options panel.

You can see that I'm calling it in the first script:


of_get_option('map_api')


I guess I can also check to see if that option field has data and if it does, show the scripts... if not, don't show the scripts. Is that possible?


Linda comments:

That might be possible. Do you have a live site I could view?


beowulf comments:

I'm developing the theme on my localhost but I can get an installation set up for preview.


Linda comments:

That's ok. What do you think about using this in the header.php

<?php
if ( is_active_widget(false, false, $this->id_base, true) ) {
wp_enqueue_script('my_script');
}
?>


and then wp_enqueue_script in the functions?


Linda comments:

@Paul. Ah ha! That is why it isn't working. That makes sense. Thanks for clarifying.

2011-06-24

Just Me answers:

How about loading it in the footer?

2011-06-24

Paul Gregory answers:

Hi. The trouble is that is_active_widget() is true for the front-end as a whole, not for individual pages. So if it's in your sidebar, and then you visit a page that doesn't even have a sidebar, then is_active_widget is still true. Possibly the Codex should make this clearer.

See: http://wordpress.org/support/topic/why-isnt-this-function-working?replies=6

You need to put add_action('wp_head', array(&$this, 'jg_widget_header') ); pr similar into the widget construct function then define the function echoing all the scripts you need.

(Your idea of using the API key runs into similar trouble; the function in your plugin/theme will have access to the theme's options almost by virtue of the fact it is being run.)


beowulf comments:

Interesting. I'll give this a try when I have a moment.

2011-06-25

Jurre Hanema answers:

Since you are writing the widget yourself, I think that this solution I found on GitHub is perfect for your situation: https://gist.github.com/392765

Basically, what happens is the following:
- In the widget constructor, the script is enqueued to be placed in the footer
- In the widget constructor, an action is created that actually <em>removes</em> the enqueued script from being loaded as soon as the footer is reached
- If the widget is rendered, the action is removed and so the script is loaded.