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.

Say I created a plugin that injects content (used as a shortcode) into a post. I'm trying to push that code for each post to the bottom of the page.

This works fine, however when you are on an archive page with multiple posts using the same shortcode, there is an obvious conflict because the function names become duplicate and it will only output the footer code (activate_flex_slider) once.

<?php
function your_function() {
    echo '<p>This is inserted at the bottom</p>';
}
add_action('wp_footer', 'your_function');
?>

What i'm trying to do is output footer script so that there are multiple jQuery instances pointing to their respective ID's...

<?php
    function flex_slider() {
        $output ='<ul class="flexslider"><li>Slide Content</li></ul>';
        return $output;
    }


    function activate_flex_slider(){
        ?>
    <script>
                ( function ($) {
             $(window).load(function(){

       //different number will be prepended to ID (matches post ID #)
      $('#carousel-<?php echo $post->ID ?>').flexslider();
    });
        })(jQuery);
    </script>
<?php
    }

    // Hook into footer so slider becomes active after page loads
    add_action('wp_footer','activate_flex_slider');

    // Create the Shortcode
    add_shortcode('flex_slider', 'flex_slider');
    ?>
share|improve this question
    
Why do you create a new function for each value? –  toscho Oct 17 '12 at 21:06
    
Updated more specific code –  Joe Oct 17 '12 at 22:39

2 Answers 2

I would wrap the whole thing in a class and put your data into a class var.

class WPA69616_Plugin {
    private $data = '';

    public function __construct() {
        add_shortcode('my_shortcode', array($this, 'add_content'));
        add_action('wp_footer', array($this, 'output_content'));
    }

    public function add_content($atts) {
        extract( shortcode_atts( array(
            'content' => ''
        ), $atts ) );
        $this->data .= $content;
    }

    public function output_content() {
        echo $this->data;
    }
}
$wpa69616_plugin = new WPA69616_Plugin();  
share|improve this answer
2  
Register the footer action later, in the shortcode callback, to avoid running it when no shortcode has been used. –  toscho Oct 17 '12 at 22:04
    
This still only outputs the footer content 1 time, even when on an archive page with multiple posts containing the shortcode. –  Joe Oct 18 '12 at 1:06
    
@Joe - in this example the line $this->data .= $content; appends whatever you pass as the content argument of the shortcode to the internal $data var, i.e. [my_shortcode content="something"], you may want to change this for your specific case, but it does indeed output multiple values for shortcodes in multiple posts. –  Milo Oct 18 '12 at 2:18

I've used Flexslider before and still had a plugin for shortcodes lying around. It's a bit dusty, but I've uploaded it to my dev install now that I came across this question and it still works (and does so with multiple sliders on the same page), so here's the main plugin file's contents:

Flexslider with WP Shortcodes

/**
 * Holds the URL
 *
 * @since 1.0
 */
if ( ! defined( 'WPSE69616_RELPATH' ) )
    define( 'WPSE69616_RELPATH', plugin_dir_url( __FILE__ ) );

if ( ! class_exists( 'WPSE69616_SLIDER' ) ) :
class WPSE69616_SLIDER {

    /**
     * Scripts & Styles
     *
     * @since 1.0
     */
    public function init() {
        /* default flexslider stylesheet */
        wp_register_style( 'wpse69616-default', WPFS_RELPATH . 'css/flexslider.css', false, '1.8' );
        /* few fixes for WP */
        wp_register_style( 'wpse69616-fixes', WPFS_RELPATH . 'css/fixes.css', false, '1.0' );
        /* the actual slider */
        wp_register_script( 'wpse69616-flexslider', WPFS_RELPATH . 'js/jquery.flexslider-min.js', array('jquery'), '1.8', true );
        /* slider initialization */
        wp_register_script( 'wpse69616-flex-init', WPFS_RELPATH . 'js/initialization.js', array('wpse69616-flexslider'), '1.0', true );
    }

    /**
     * Slider Shortcodes
     *
     * @since 1.0
     */
    public function slider( $atts, $content='' ) {
        wp_enqueue_style( 'wpse69616-default' );
        wp_enqueue_style( 'wpse69616-fixes' );
        wp_enqueue_script( 'wpse69616-flexslider' );
        wp_enqueue_script( 'wpse69616-flex-init' );
        extract( shortcode_atts( array(
            'id' => ''
        ), $atts ) );
        $id = ! empty( $id ) ? ' id="' . $id . '"' : '';
        $content = do_shortcode( $content );

        return '<div' . $id . ' class="flexslider">' .
                '<ul class="slides">' . $content . '</ul>' .
            '</div>';
    }
    public function slide( $atts, $content='' ) {
        $content = do_shortcode( $content );
        return '<li>' . $content . '</li>';
    }

    /**
     * Class Constructor
     *
     * @since 1.0
     */
    public function __construct() {
        add_action( 'wp_loaded', array( &$this, 'init' ) );
        add_shortcode( 'slide', array( &$this, 'slide' ) );
        add_shortcode( 'flexslider', array( &$this, 'slider' ) );
    }

} // class
endif; // class exists

$wpse69616_slider = new WPSE69616_SLIDER();

In this plugin I initialize all the sliders with the same properties, so for the initialization.js above

jQuery(window).load(function() {
    jQuery('.flexslider').flexslider( {
        slideshow: false,
        controlNav: true,
        prevText: "<",
        nextText: ">",
    });
});

will suffice.

Note that you only need multiple jQuery functions if you want to use the slider with different properties each time. Otherwise you can target all of them by using a class as a selector (as is done above).

Varying Properties

If you must have varying properties, this is how that'd be done (I will assume you have an array of properties from somewhere - postmeta, options, whatever). The array would look like this:

$slider_properties = array(
    array(
        'id' => 53 // some post ID
        'slideshow' => 'false',
        'controlNav' => 'true'
    ),
    array(
        'id' => 101 // some post ID
        'slideshow' => 'true',
        'controlNav' => 'false'
    )
);

And then you could add

wp_localize_script( 'wpse69616-flex-init', 'wpseSlider', $slider_properties );

to the main plugin class and as for the js do

(function($) {
    $(window).load(function() {
        for( var i=0; i<wpseSlider.length; i++ ) {
            $( '#carousel-' + wpseSlider[i].id ).flexslider( {
                slideshow: wpseSlider[i].slideshow,
                controlNav: wpseSlider[i].controlNav,
                prevText: "<",
                nextText: ">",
            });
        }
    });
})(jQuery);

And with that you'd have multiple instances of the slider, each with it's own set of arguments.

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.