Criando vários wp_localize_script para Shortcode?

4

Eu tenho um shortcode que exibe produtos recentes do WooCommerce em um carrossel, mas gostaria que o usuário final pudesse usar o shortcode várias vezes na mesma página, atualmente, quando isso acontece, o carrossel do jQuery tem conflitos.

Aqui está o código que estou usando para o shortcode,

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 o jQuery eu uso o seguinte,

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,

    });
});

Eu sei por que isso não está funcionando, mas não tenho certeza qual é a melhor solução, o identificador 'carouselvars' no wp_localize_script está sendo chamado sem um nome exclusivo, então a variável está sendo chamada duas vezes.

Qualquer solução muito apreciada.

Atenciosamente

    
por Shoebox 24.02.2014 / 22:18

2 respostas

3

Não sou especialista em jQuery, mas deparei com o mesmo problema e acredito que tenho uma solução viável. O problema é que toda vez que você executa o wp_localize_script, ele cria uma variável javascript usando a configuração $ name. No seu caso, isso é 'carouselvars'. Como isso é definido antes do jQuery em execução, somente os últimos valores passados para a variável são 'vistos' por jQuery, então, novamente no seu caso, settingObj.autoscroll sempre será o valor definido na última instância do shortcode .

Minha solução é definir um nome de variável dinâmica para a chamada wp_localize_script, algo como:

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

em que $ instance pode ser o que o usuário quiser definir. Então, o uso seria:

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

e seu código para extrair as configurações precisariam 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));

Tenho certeza de que há uma maneira mais inteligente de fazer isso, portanto nenhuma instância precisa ser definida, mas, como eu disse, não sou especialista em jQuery.

Em seguida, o truque é obter os dados corretos para acessar a instância correta do shortcode. Eu fiz isso usando tipos de dados html5. Então, na parte php do seu código, acho que seria melhor fazer isso:

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

Então o seu jQuery ficaria assim:

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,

        });
    });
}

Portanto, este script jQuery fará um loop em cada instância de '.owl-carrossel' e executará a função SetOwlCarousel nele. Chamar o objeto window ao definir settingObj permite que você avalie "carouselvars" + instance para a variável que você definiu usando wp_localize_script, portanto, no meu exemplo carouselvars1 e carouselvars2.

Se alguém tiver uma maneira mais limpa de fazer isso, eu adoraria usá-lo, mas isso deve dar a você o que você está procurando. Eu não testei este código, mas é substancialmente o mesmo que eu usei, o que funcionou.

    
por MatthewLee 17.03.2014 / 23:54
0

Fornecer tudo o mais está funcionando - para usar um código para segmentar o controle deslizante, ele deve ser exclusivo. Portanto, todos os contêineres deslizantes não podem ter um ID de #owl-example - ele precisa ser #owl-example-1 , #owl-example-2 etc.

Para evitar isso, você pode tentar usar a classe .owl-carousel .

    
por Steven Jones 25.02.2014 / 11:10