Создание нескольких сценариев локализации wp для шорткода?
У меня есть шорткод, который отображает последние продукты WooCommerce в карусели, однако я хотел бы, чтобы конечный пользователь мог использовать шорткод несколько раз на одной странице, в настоящее время, когда это происходит, в карусели jQuery возникают конфликты.
Вот код, который я использую для шорткода,
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');
Для jQuery я использую следующее,
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,
});
});
Я знаю, почему это не работает, но не уверен, что это лучшее решение, ручка "карусели" в wp_localize_script вызывается без уникального имени, поэтому переменная вызывается дважды.
Любые решения очень ценятся.
С уважением
2 answers
Я не эксперт по jQuery, но я столкнулся с той же проблемой и считаю, что у меня есть приемлемое решение. Проблема в том, что каждый раз, когда вы запускаете wp_localize_script, он создает переменную javascript с использованием параметра $name. В вашем случае это "карусели". Поскольку это задано перед запуском jQuery, jQuery "видит" только последние значения, переданные в переменную, поэтому, опять же, в вашем случае значение settingObj.autoscroll всегда будет таким, какое значение было установлено в последнем экземпляре короткий код.
Мое решение состоит в том, чтобы задать имя динамической переменной для вызова wp_localize_script, что-то вроде:
wp_localize_script('owlcarouselcustom', 'carouselvars' . $instance, array(
'autoscroll' => $autoscroll
)
);
Где $instance может быть любым значением, которое пользователь хочет установить. Таким образом, использование будет следующим:
[recent_products_slider instance=1 autoscroll=0]
[recent_products_slider instance=2 autoscroll=1]
И ваш код для извлечения настроек должен быть следующим:
extract(shortcode_atts(array(
'title' => 'Recent Products',
'order' => 'DESC',
'orderby' => 'date',
'mousewheel' => 'false',
'autoscroll' => '1',
'swipe' => 'false',
'scroll' => '1',
'items' => 6,
'instance' => 1
), $atts));
Я уверен, что есть более умный способ сделать это, поэтому не нужно устанавливать экземпляр, но, как я уже сказал, я не эксперт в jQuery.
Тогда весь фокус в том, чтобы получить правильные данные для перейдите в нужный экземпляр шорткода. Я сделал это, используя типы данных html5. Поэтому в части php вашего кода, я думаю, было бы лучше сделать это:
<div id="owl-' . $instance . '" class="owl-carousel" data-instance="' . $instance . '">
Тогда ваш jQuery будет выглядеть так:
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,
});
});
}
Таким образом, этот скрипт jQuery будет выполнять цикл над каждым экземпляром ".owl-карусели" и запускать на нем функцию SetOwlCarousel. Вызов объекта window при установке settingobj позволяет оценить экземпляр "carouselvars"+ для переменной, которую вы задали с помощью wp_localize_script, поэтому в моем пример carouselvars1 и carouselvars2.
Если у кого-то есть более чистый способ сделать это, я бы с удовольствием им воспользовался, но это должно дать вам то, что вы ищете. Я не тестировал этот код, но он по существу такой же, как тот, который я использовал сам, который работал.
При условии, что все остальное работает - для того, чтобы использовать идентификатор для настройки слайдера, он должен быть уникальным. Поэтому все контейнеры слайдера не могут иметь идентификатор #owl-example
- он должен быть #owl-example-1
, #owl-example-2
и т.д.
Чтобы полностью избежать этого, вы можете попробовать вместо этого использовать класс .owl-carousel
.