Создание нескольких сценариев локализации 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 вызывается без уникального имени, поэтому переменная вызывается дважды.

Любые решения очень ценятся.

С уважением

Author: Shoebox, 2014-02-24

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.

Если у кого-то есть более чистый способ сделать это, я бы с удовольствием им воспользовался, но это должно дать вам то, что вы ищете. Я не тестировал этот код, но он по существу такой же, как тот, который я использовал сам, который работал.

 5
Author: MatthewLee, 2014-03-17 22:54:55

При условии, что все остальное работает - для того, чтобы использовать идентификатор для настройки слайдера, он должен быть уникальным. Поэтому все контейнеры слайдера не могут иметь идентификатор #owl-example - он должен быть #owl-example-1, #owl-example-2 и т.д.

Чтобы полностью избежать этого, вы можете попробовать вместо этого использовать класс .owl-carousel.

 0
Author: Steven Jones, 2014-02-25 10:10:19