J'ai un shortcode qui affiche les produits WooCommerce récents dans un carrousel. Cependant, j'aimerais que l'utilisateur final puisse utiliser le shortcode plusieurs fois sur la même page. Actuellement, le carrousel jQuery présente des conflits.
Voici le code que j'utilise pour le 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');
Pour le jQuery j'utilise ce qui suit,
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,
});
});
Je sais pourquoi cela ne fonctionne pas, mais je ne sais pas quelle est la meilleure solution. Le descripteur 'carrouselvars' dans le script wp_localize_script est appelé sans nom unique et la variable est appelée deux fois.
Toutes les solutions sont très appréciées.
Sincères amitiés
Je ne suis pas un expert de jQuery, mais j'ai rencontré le même problème et je pense avoir une solution viable. Le problème est que chaque fois que vous exécutez wp_localize_script, il crée une variable javascript à l'aide du paramètre $ name. Dans votre cas, il s'agit de "carrouselvars". Comme cela est défini avant l'exécution de jQuery, seules les dernières valeurs transmises à la variable sont "vues" par jQuery. Par conséquent, dans votre cas, settingObj.autoscroll sera toujours quelle que soit la valeur définie dans la dernière instance du shortcode. .
Ma solution consiste à définir un nom de variable dynamique pour l'appel wp_localize_script, comme suit:
wp_localize_script('owlcarouselcustom', 'carouselvars' . $instance, array(
'autoscroll' => $autoscroll
)
);
où $ instance peut être celui que l'utilisateur souhaite définir. Donc, l'utilisation serait:
[recent_products_slider instance=1 autoscroll=0]
[recent_products_slider instance=2 autoscroll=1]
et votre code pour extraire les paramètres doit être:
extract(shortcode_atts(array(
'title' => 'Recent Products',
'order' => 'DESC',
'orderby' => 'date',
'mousewheel' => 'false',
'autoscroll' => '1',
'swipe' => 'false',
'scroll' => '1',
'items' => 6,
'instance' => 1
), $atts));
Je suis sûr qu'il existe un moyen plus astucieux de le faire. Aucun cas ne doit donc être défini, mais, comme je l'ai dit, je ne suis pas un expert en jQuery.
Ensuite, l'astuce consiste à obtenir les bonnes données pour les insérer dans la bonne instance du shortcode. Je l'ai fait en utilisant les types de données html5. Donc, dans la partie php de votre code, je pense qu'il serait préférable de faire ceci:
<div id="owl-' . $instance . '" class="owl-carousel" data-instance="' . $instance . '">
Ensuite, votre jQuery ressemblerait à ceci:
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,
});
});
}
Donc, ce script jQuery passera en boucle sur chaque instance de '.owl-carrousel' et exécutera la fonction SetOwlCarousel sur celle-ci. L'appel de l'objet window lorsque vous définissez settingObj vous permet d'évaluer "carouselvars" + instance avec la variable que vous définissez à l'aide de wp_localize_script. Dans mon exemple, carouselvars1 et carouselvars2.
Si quelqu'un a une méthode plus propre pour le faire, j'aimerais bien l'utiliser, mais cela devrait vous permettre d'obtenir ce que vous recherchez. Je n'ai pas testé ce code, mais il est sensiblement le même que celui que j'ai utilisé moi-même et qui a fonctionné.
Tout le reste fonctionne - pour utiliser un ID pour cibler le curseur, il doit être unique. Par conséquent, tous les conteneurs de curseur ne peuvent pas avoir un ID de #owl-example
- il doit être #owl-example-1
, #owl-example-2
, etc.
Pour éviter cela complètement, essayez d’utiliser plutôt la classe .owl-carousel
.