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'm not sure why this script is not loading or producing any load errors via Firebug. Here is my plugin script:

class AV_Slideshow{ 

function __construct(){
    $this->hooks();
}
function hooks(){
    add_action('wp_head', array( $this, 'load_av_slider' ));
}   
function load_av_slider(){
    wp_register_script('av-slideshow', get_bloginfo('stylesheet_directory') . '/js/AV-Slideshow/av_slideshow.js', array('jquery') );
    wp_enqueue_script('av-slideshow' );
}

function build_slideshow($slides){

    if(!$slides){$slideshow = 'No posts are selected for this slideshow.';}

        $slideshow = '<div id="slides"><div class="slides_container">';
        foreach($slides as $post_id){
            $post = get_post($post_id);
            $title = $post->post_title;
            $content = $post->post_content;

            $slideshow .= '<span>' . $title . '</span><span>' . $content . '</span>';
        }
        $slideshow .= '</div></div>';

        return $slideshow;
}

}

add_shortcode( 'slideshow', array('AV_Slideshow', 'build_slideshow') );

?>

The $slideshow output is working but the script never loads. Am I loading this correctly?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

The class constructor method isn't called until your shortcode handler is (i.e. when WordPress is searching the post content for shortcodes). This is done after wp_head is called, so you're missing the boat.

However, you don't need to enqueue scripts on your wp_head - and doing so for shortcodes/widgets which may not be on every page is a waste. Since 3.3 you can call wp_enqueue_script inside the shortcode/widget callback, and doing so means your script is enqueued only on pages where it is absolutely needed. The script is then printed in the footer.

class AV_Slideshow{ 

function build_slideshow($slides){

    if(!$slides){$slideshow = 'No posts are selected for this slideshow.';}

        $slideshow = '<div id="slides"><div class="slides_container">';
        foreach($slides as $post_id){
            $post = get_post($post_id);
            $title = $post->post_title;
            $content = $post->post_content;

            $slideshow .= '<span>' . $title . '</span><span>' . $content . '</span>';
        }
        $slideshow .= '</div></div>';

        //Shortcode is being used, so enqueue the script:
        wp_enqueue_script('av-slideshow', get_bloginfo('stylesheet_directory') .  '/js/AV-Slideshow/av_slideshow.js', array('jquery') );

        return $slideshow;
}

}

add_shortcode( 'slideshow', array('AV_Slideshow', 'build_slideshow') );

After that slimming down, the class structure seems a bit unnecessary. But I tend to put all my plug-in's shortcodes into one class - particularly when the shortcodes are sharing scripts/styles and I need to print JavaScript variables to the page.

share|improve this answer
    
You know what's interesting is that you can call wp_enqueue_script but not wp_enqueue_style. –  AlxVallejo Jul 4 '12 at 0:41
    
What do you mean? The same applies to wp_enqueue_style. –  Stephen Harris Jul 4 '12 at 7:28

Your first problem is the hook your calling to enqueue your scripts. Change that line to...

function hooks() {
    add_action('wp_enqueue_scripts', array($this, 'load_av_slider'));
}

There is also a glaring omission which I was going to ignore. You arent instantiating an object of your class. I was assuming you just didn't include it in your example, but if you just forgot to do it, then that would definitely result in never loading the scripts since the constructor would never be called.

My recommendation is the following...

class AV_Slideshow {

    function __construct() {
        $this->hooks();
    }

    function hooks() {
        add_action('wp_enqueue_scripts', array($this, 'load_av_slider'));
    }

    function load_av_slider() {
        wp_register_script('av-slideshow', get_bloginfo('stylesheet_directory') . '/js/AV-Slideshow/av_slideshow.js', array('jquery'));
        wp_enqueue_script('av-slideshow');
    }

    function build_slideshow($slides) {

        if (!$slides) {
            $slideshow = 'No posts are selected for this slideshow.';
        }

        $slideshow = '<div id="slides"><div class="slides_container">';
        foreach ($slides as $post_id) {
            $post = get_post($post_id);
            $title = $post->post_title;
            $content = $post->post_content;

            $slideshow .= '<span>' . $title . '</span><span>' . $content . '</span>';
        }
        $slideshow .= '</div></div>';

        return $slideshow;
    }

}

$avs = new AV_Slideshow();

add_shortcode('slideshow', array($avs, 'build_slideshow'));

If your going to use $this references you definitely need to instantiate an object of your class. After than you can go ahead and still pass the context parameter statically the way you were doing, however it can lead to confusion later on down the road if your expand on your code. Unless you meant to have build_slideshow() static, and the rest objective for a specific reason, you should stick to one or the other. Not much reason to go objective, but I kept it that way since its what you had.

share|improve this answer

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.