I created a Wordpress plug which provides a custom post type (Slides) and these can be grouped by a taxonomy (Slideshows). Using a shortcode [slides], you can display these Slides and filter them by Slideshow. Here's how I coded the shortcode:
function slds_shortcode( $atts ) {
extract( shortcode_atts( array(
'slideshow' => 'all',
'timeout' => '5000',
), $atts ) );
$slideshow = $atts[slideshow];
global $post;
$tmp_post = $post;
$args = array( 'slideshows' => $slideshow, 'timeout' => $timeout, );
$myposts = get_posts( $args );
ob_start(); // Helps output the HTML where the shortcode is (otherwise it outputs before the content).
?>
<div id="<?php echo $slideshow; ?>" class="slds-slideshow">
<div class="timeout-<?php echo $timeout; ?>">
<?php foreach( $myposts as $post ) : setup_postdata($post); ?>
<div class="slide">
<?php the_content(); ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
$post = $tmp_post;
return ob_get_clean();
}
add_shortcode('slides', 'slds_shortcode');
The scripts and stylesheet are included in the footer, only if a shortcode is found in the post. The script (responsiveslides.js) requires an init, which currently outputs in the footer whether a shortcode is found in the post or not. Here's how I generate that:
function slds_init() {
echo '
<script>
jQuery(function($) {
$(document).ready(function() {
$(".slds-slideshow .timeout-5000").responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: 5000,
speed: 1800
});
$(".slds-slideshow .timeout-10000").responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: 10000,
speed: 1800
});
});
});
</script>';
}
add_action('wp_footer', 'slds_init');
This works great, so long as the defaults I coded in there are suitable for the project. Instead, I'd like to be able to set these parameters in the shortcode like: [slides slideshow=tour timeout=10000 speed=1200]. As you can see above, the init has a few major limitations. It selects ALL instances of .slds-slideshow instead of selecting each shortcode output individually by a unique id or class, meaning these default parameters have to be used for all shortcode outputs. In fact, the reason I have two jQuery selectors is so I can add an alternate .timeout class to the output, which just changes which jQuery selector is affecting the shortcode output (or slideshow HTML if you will). This is a shoddy solution. Obviously if I relied on classes for all the parameters this way, with the virtually infinite number of parameter combinations, the init would become extremely heavy and clunky.
How can I generate that middle section of the init (the jQuery selectors and their parameters) based on the shortcode attributes in such a way that they still correlate to the HTML output of the shortcodes in the post?
Edit
Thanks again @birgire for your ideas! I think they got me much closer to where I need to be.
I tried out a lot of options. I think the main thing I'm still running into is getting shortcode instances to generate anything in my javascript initialization. I put wp_localize_script() in my shortcode function as @birgire suggested:
wp_localize_script('slds_script', 'slds_vars', array(
'instance' => $instance,
'timeout' => $timeout,
'speed' => $speed
));
So with two shortcodes on the page with timeout
and speed
set differently, I now get:
/* <![CDATA[ */
var avrgslds_vars = {"instance":"53442837d55c2","timeout":"10000","speed":"500"};
var avrgslds_vars = {"instance":"5344283814479","timeout":"5000","speed":"200"};
/* ]]> */
(I set a new variable for the instance: $instance = uniqid();
)
That seems like a significant improvement! So in my javascript initialization, I tried echoing a variable set in my shortcode, which would have all the shortcode "atts" (parameters):
$jQselectors = "";
$jQselectors .= " // Hoping this will keep the array keys from overwriting eachother.
$(slds_vars.instance).responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: $timeout,
speed: $speed
});
";
Of course, I realized after I saw this result...
<script>
jQuery(function($) {
$(document).ready(function() {
});
});
</script>
I can't select the variable from outside my shortcode function like I was attempt to do:
function slds_init() { ?>
<script>
jQuery(function($) {
$(document).ready(function() {
<?php echo $jQselectors; ?>
});
});
</script>
<?php
}
add_action('wp_footer', 'slds_init'); }
I'm having trouble wrapping my head around how to do this. I may just have a misunderstanding on how arrays work. Any ideas? Any/all help is greatly appreciated.