¿Creando múltiples wp_localize_script para Shortcode?

4

Tengo un shortcode que muestra los productos recientes de WooCommerce en un carrusel, sin embargo, me gustaría que el usuario final pueda usar el shortcode varias veces en la misma página, actualmente cuando esto sucede, el carrusel jQuery tiene conflictos.

Aquí está el código que estoy usando para el código corto,

function recent_products_slider_func($atts) {
global $woocommerce_loop;
static $count = 0;
if (empty($atts)) return;

extract(shortcode_atts(array(
    'title'            => 'Recent Products',
    'order'         => 'DESC',
    'orderby'         => 'date',
    'mousewheel'     => 'false',
    'autoscroll'     => '1',
    'swipe'         => 'false',
    'scroll'         => '1',
    'items'         => 6
), $atts));

$args = array(
    'post_type'    => 'product',
    'post_status' => 'publish',
    'posts_per_page' => $items,
    'ignore_sticky_posts'    => 1,
    'orderby' => $orderby,
    'order' => $order,
    'meta_query' => array(
        array(
            'key'         => '_visibility',
            'value'     => array('catalog', 'visible'),
            'compare'     => 'IN'
        )
    )
);
wp_enqueue_script('owlcarouselcustom', get_template_directory_uri() . '/includes/pixelstores/shortcodes/js/' . 'owlcarousel.js');
wp_localize_script('owlcarouselcustom', 'carouselvars', array(
  'autoscroll' => $autoscroll
  )
);

ob_start();

$products = new WP_Query( $args );

if ( $products->have_posts() ) : ?>

    <div class="row ps-carousel">
        <div class="col-xs-10">        
            <h3><?php echo $title; ?></h3>
        </div>
        <div class="col-xs-2">
            <div class="ps-carousel-btns">        
                <a class="btn prev"><i class="fa fa-angle-left" /></a>
                <a class="btn next"><i class="fa fa-angle-right" /></a>
            </div>    
        </div>    
    </div>

    <div class="row">
        <div id="owl-example" class="owl-carousel">
            <?php while ( $products->have_posts() ) : $products->the_post(); ?>
                <?php if ( class_exists('woocommerce') ) {  woocommerce_get_template_part( 'content', 'product' ); } ?>
            <?php endwhile; ?>
        </div>
    </div>

<?php endif; 

wp_reset_query();       
$count++;                  

return ob_get_clean();
}                  
add_shortcode('recent_products_slider', 'recent_products_slider_func'); 

Para jQuery, uso lo siguiente,

jQuery(document).ready(function($) {
var settingObj = carouselvars;
var owlcontainer = $("#owl-example");

if(settingObj.autoscroll == 1) {settingObj.autoscroll = true;} else {settingObj.autoscroll = false;}

$(owlcontainer).owlCarousel({
    autoPlay: settingObj.autoscroll,

    });
});

Sé por qué esto no funciona, pero no estoy seguro de cuál es la mejor solución, el identificador de 'carouselvars' en el wp_localize_script se está invocando sin un nombre único, por lo que la variable se llama dos veces.

Cualquier solución muy apreciada.

Saludos cordiales

    
pregunta Shoebox 24.02.2014 - 22:18

2 respuestas

3

No soy un experto en jQuery, pero me encontré con el mismo problema y creo que tengo una solución viable. El problema es que cada vez que ejecutas wp_localize_script, crea una variable javascript usando la configuración $ name. En tu caso eso es 'carouselvars'. Como esto se establece antes de jQuery en ejecución, solo jQuery 've' solo los últimos valores pasados a la variable, así que nuevamente en su caso, settingObj.autoscroll siempre será el valor que se configuró en la última instancia del código abreviado .

Mi solución es establecer un nombre de variable dinámica para la llamada wp_localize_script, algo como:

wp_localize_script('owlcarouselcustom', 'carouselvars' . $instance, array(
  'autoscroll' => $autoscroll
  )
);

donde $ instance puede ser lo que el usuario quiera configurar. Así que el uso sería:

[recent_products_slider instance=1 autoscroll=0]
[recent_products_slider instance=2 autoscroll=1]

y su código para extraer la configuración debería ser:

extract(shortcode_atts(array(
    'title'            => 'Recent Products',
    'order'         => 'DESC',
    'orderby'         => 'date',
    'mousewheel'     => 'false',
    'autoscroll'     => '1',
    'swipe'         => 'false',
    'scroll'         => '1',
    'items'         => 6,
    'instance'      => 1
), $atts));

Estoy seguro de que hay una forma más inteligente de hacerlo, por lo que no es necesario establecer una instancia, pero, como dije, no soy un experto en jQuery.

Entonces, el truco es conseguir que los datos correctos lleguen a la instancia correcta del código abreviado. Lo hice usando tipos de datos html5. Así que en la parte de php de su código, creo que sería mejor hacer esto:

<div id="owl-' . $instance . '" class="owl-carousel" data-instance="' . $instance . '">

Entonces tu jQuery se vería así:

jQuery(document).ready(function($) {
    $('.owl-carousel').each(function( index ) {
        var instance = $( this ).data('instance');
        SetOwlCarousel(instance);
    });
});

function SetOwlCarousel(instance) {
    var settingObj = window["carouselvars"+instance];
    var owlcontainer = $("#owl-" + instance);

    if(settingObj.autoscroll == 1) {settingObj.autoscroll = true;} else {settingObj.autoscroll = false;}

    jQuery(owlcontainer).owlCarousel({
        autoPlay: settingObj.autoscroll,

        });
    });
}

Entonces, esta secuencia de comandos jQuery se desplazará sobre cada instancia de '.owl-carousel' y ejecutará la función SetOwlCarousel en ella. Al llamar al objeto de la ventana cuando establece settingObj, puede evaluar la instancia de "carouselvars" + con la variable que estableció usando wp_localize_script, así que en mi ejemplo carouselvars1 y carouselvars2.

Si alguien tiene una forma más limpia de hacer esto, me encantaría usarlo, pero esto debería darle lo que está buscando. No he probado este código, pero es sustancialmente el mismo que el que utilicé, que funcionó.

    
respondido por el MatthewLee 17.03.2014 - 23:54
0

Proporcionar todo lo demás está funcionando: para poder usar una ID para apuntar al control deslizante, debe ser único. Por lo tanto, todos los contenedores del control deslizante no pueden tener un ID de #owl-example ; debe ser #owl-example-1 , #owl-example-2 etc.

Para evitar esto por completo, puede intentar usar la clase .owl-carousel en su lugar.

    
respondido por el Steven Jones 25.02.2014 - 11:10

Lea otras preguntas en las etiquetas