Localize variable for multiple Shortcodes

I have this code for flexslider Shortcode

add_shortcode('flexslider', function($atts){
global $post;
$ids = explode(',', $atts[ids]);

$uniqid = uniqid();
wp_enqueue_script( 'shortcode_flexslider');
wp_localize_script( 'shortcode_flexslider', 'slider', array('id' => $uniqid)); 

foreach( $ids as $id ) {
    $imgLinks       = wp_get_attachment_image_src($id, large);
    $imgThumb       = wp_get_attachment_image_src($id, thumbnail);

    $slider     .= '<li><img src="'.$imgLinks[0].'">'.$imgCaptionContent.'</li>';
    $carousel   .= '<li><img src="'.$imgThumb[0].'"></li>'; 
}
$structure="<div id="slider".$uniqid.'" class="flexslider"><ul class="slides">'
            .$slider.
            '</ul></div>'.

            '<div id="carousel'.$uniqid.'" class="flexslider"><ul class="slides">'
            .$carousel.
            '</ul></div>';   
});

I put uniqid for slider and carousel ids to can put more one flexslider Shortcode in the same post and I localize the uniqid to shortcode_flexslider JS file to find slider and carousel ids

$('#carousel'+slider.id).flexslider({
  //
   asNavFor: '#slider'+slider.id
  //
});

$('#slider'+slider.id).flexslider({
 //
  sync: '#carousel'+slider.id
//
});

The problem is when I put more one flexslider Shortcode in the same post the localized variable slider.id get the last flexslider Shortcode uniqid , so the last flexslider Shortcode is only that works ,how i can pass all flexslider Shortcode uniqid not just the last one?

2 Answers
2

Your ploblem is that wp_localize_script print to the html markup a javascript object similar to:

var slider = {"id":"a_unique_id_here"};

if you call it more times, e.g. using more shortcodes in same page, whati is printend in html markup is

var slider = {"id":"a_unique_id_here"};
var slider = {"id":"another_unique_id_here"};
var slider = {"id":"third_unique_id_here"};

so you are overwriting again and again the same variable.

You need this sort of thing, you should transform the output in something like this:

var slider_ddAsfe2ser = {"id":"a_unique_id_here"};
var slider_fsdgffereR = {"id":"another_unique_id_here"};
var slider_d4frfAd1ej = {"id":"third_unique_id_here"};

I.E. you have to create an unique named variable as settings object for every shorcode.

How? Something like:

add_shortcode('flexslider', function($atts) {
  global $post;
  $ids = explode(',', $atts[ids]);
  $uniqid = uniqid();
  wp_enqueue_script( 'shortcode_flexslider');
  $token = wp_generate_password(32, false, false);
  wp_localize_script( 'shortcode_flexslider', 'slider_' . $token, array('id' => $uniqid));
  foreach( $ids as $id ) {
    // ... your code here ...
  }
  $structure="<div id="slider" . $uniqid. '" class="flexslider"';
  $structure .= ' data-token="' . $token . '">'; // the token as data attribute
  $structure .= '<ul class="slides">' . $slider . '</ul></div>';
  $structure .= '<div id="carousel' . $uniqid . '" class="flexslider">';
  $structure .= '<ul class="slides">' . $carousel . '</ul></div>'
});

After that in your js:

// cicle all the divs with 'flexslider' class and id that starts with 'slider'
$('div.flexslider[id^="slider"]').each( function() { 
  var $div = $(this); // the sdiv jquery object
  var token = $div.data('token');
  // use the bracket syntax to retrieve the unique named object
  // in the global (window) scope
  var settingObj = window['slider_' + token];
  $div.flexslider({
    //
    sync: '#carousel' + settingObj.id
    //
  });
  $carousel = $( '#carousel' + settingObj.id); // the carousel div jquery object
  $carousel.flexslider({
    //
    asNavFor: '#slider' + settingObj.id
    //
  });
}); // end each cycle

Leave a Comment