Wordpress - Loading scripts only if a particular shortcode or widget is present
You can use the function is_active_widget . E.g.:
function check_widget() {
if( is_active_widget( '', '', 'search' ) ) { // check if search widget is used
wp_enqueue_script('my-script');
}
}
add_action( 'init', 'check_widget' );
To load the script in the page where the widget is loaded only, you will have to add the is_active_widget() code, in you widget class. E.g., see the default recent comments widget (wp-includes/default-widgets.php, line 602):
class WP_Widget_Recent_Comments extends WP_Widget {
function WP_Widget_Recent_Comments() {
$widget_ops = array('classname' => 'widget_recent_comments', 'description' => __( 'The most recent comments' ) );
$this->WP_Widget('recent-comments', __('Recent Comments'), $widget_ops);
$this->alt_option_name = 'widget_recent_comments';
if ( is_active_widget(false, false, $this->id_base) )
add_action( 'wp_head', array(&$this, 'recent_comments_style') );
add_action( 'comment_post', array(&$this, 'flush_widget_cache') );
add_action( 'transition_comment_status', array(&$this, 'flush_widget_cache') );
}
Just wanted to share a solution I worked on which allowed me to be a bit more versatile with my implementation. Rather than having the function check for a variety of shortcodes, I modified it to seek out a single shortcode that references a script/style function that needs to be enqueued. This will work for both methods in other classes (such as plugins that may not do this themselves) and in-scope functions. Just drop the below code in functions.php and add the following syntax to any page/post where you want specific CSS & JS.
Page/Post Syntax: [loadCSSandJS function="(class->method/function name)"]
functions.php code:
function page_specific_CSSandJS( $posts ) {
if ( empty( $posts ) )
return $posts;
foreach ($posts as $post) {
$returnValue = preg_match_all('#\[loadCSSandJS function="([A-z\-\>]+)"\]#i', $post->post_content, $types);
foreach($types[1] as $type) {
$items = explode("->",$type);
if (count($items) == 2) {
global $$items[0];
if( method_exists( $$items[0], $items[1] ))
add_action( 'wp_enqueue_scripts', array(&$$items[0], $items[1]) );
}
else if( !empty( $type ) && function_exists( $type ))
add_action( 'wp_enqueue_scripts', $type );
}
}
return $posts;
}
This will also allow you to add as many as you want on a page. Keep in mind that you do need a method/function to load.
with Wordpress 4.7 there is another way to achieve this in your functions.php
file,
add_action( 'wp_enqueue_scripts', 'register_my_script');
function register_my_script(){
wp_register_script('my-shortcode-js',$src, $dependency, $version, $inFooter);
}
first you register your script, which doesn't actually get printed on your page unless your enqueue it if your shortcode is called,
add_filter( 'do_shortcode_tag','enqueue_my_script',10,3);
function enqueue_my_script($output, $tag, $attr){
if('myShortcode' != $tag){ //make sure it is the right shortcode
return $output;
}
if(!isset($attr['id'])){ //you can even check for specific attributes
return $output;
}
wp_enqueue_script('my-shortcode-js'); //enqueue your script for printing
return $output;
}
the do_shortcode_tag
was introduced in WP 4.7 and can be found in the new developers documentation pages.