Добавление на сайт AJAX фильтра записей (типов постов) по рубрикам (таксономиям), произвольным полям либо по дате. Сортировка по убыванию / возрастанию.

В последнее время замечаю, что всё больше постов публикуются по просьбам читателей, так что пишите, возможно и для вас разберу какую-нибудь тему 🙂

Сейчас я покажу вам, как легко и просто создавать асинхронные фильтры записей/товаров (и те и вторые — это произвольные типы постов) на сайте при помощи всего лишь jQuery и WP_Query.

Для простоты не буду загружать пост ничем лишнем — рассмотрю только фильтрацию массива аргументов, постраничной навигации не будет, чтобы не усложнять пример. При необходимости могу дать подсказки по постраничной навигации в комментариях.

1. HTML форма фильтра

Форма будет состоять из выпадающего списка таксономий (для простоты — рубрик), диапазона значений произвольного поля (например пусть это будет цена), радио-кнопок сортировки по дате, по убыванию и возрастанию, а также чекбокса, который позволит отфильтровать посты, отобразив только те из них, у которых имеется миниатюра.

Таксономии

Неважно, элементы какой таксономии вы хотите вывести, в любых случаях функция get_terms() мне кажется ну самым удобным вариантом.

Для того, чтобы вывести элемент выпадающего списка с её помощью, вы можете воспользоваться следующим кодом:

if( $terms = get_terms( 'category', 'orderby=name' ) ) : // как я уже говорил, для простоты возьму рубрики category, но get_terms() позволяет работать с любой таксономией
    echo '<select name="categoryfilter"><option>Выберите категорию...</option>';
    foreach ($terms as $term) :
        echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // в качестве value я взял ID рубрики
    endforeach;
    echo '</select>';
endif;

Произвольные поля

Для примера возьмём минимальную и максимальную цену.

Ну тут всё легко, можно просто использовать два HTML-инпута. Конечно, будет гораздо интереснее элемент range с возможностью передвигания ползунков минимального и максимального значения. Но это уже на ваше усмотрение, плагинов jQuery много, что-нибудь да выберете.

<input type="text" name="cena_min" placeholder="Минимальная цена" />
<input type="text" name="cena_max" placeholder="Максимальная цена" />

Дата

Как я уже писал выше — это будут две radio-кнопки.

<label><input type="radio" name="date" value="ASC" /> Дата: по возрастанию</label>
<label><input type="radio" name="date" value="DESC" selected="selected" /> Дата: по убыванию</label>

Чекбокс «Только с фото»

Ну тут вообще всё просто.

<label><input type="checkbox" name="featured_image" /> Только с миниатюрой</label>

Форма целиком

Так как данная статья относится к разделу для начинающих, то не поленюсь теперь подвести итог и скинуть весь код получившейся формы.

<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<?php
if( $terms = get_terms( 'category', 'orderby=name' ) ) : // как я уже говорил, для простоты возьму рубрики category, но get_terms() позволяет работать с любой таксономией
    echo '<select name="categoryfilter"><option>Выберите категорию...</option>'
    foreach ($terms as $term) :
        echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // в качестве value я взял ID рубрики
    endforeach;
    echo '</select>';
endif;
?>
<input type="text" name="cena_min" placeholder="Минимальная цена" />
<input type="text" name="cena_max" placeholder="Максимальная цена" />
<label><input type="radio" name="date" value="ASC" /> Дата: по возрастанию</label>
<label><input type="radio" name="date" value="DESC" selected="selected" /> Дата: по убыванию</label>
<label><input type="checkbox" name="featured_image" /> Только с миниатюрой</label>
<button>Применить фильтр</button>
<input type="hidden" name="action" value="myfilter">
</form>
<div id="response"></div>

2. jQuery-скрипт для отправки запроса и получения данных

Тут я подразумеваю, что вы уже знаете, что такое jQuery и умеете его как минимум подключать на сайт.

jQuery(function($){
    $('#filter').submit(function(){
        var filter = $(this);
        $.ajax({
            url:ajaxurl, // обработчик
            data:filter.serialize(), // данные
            type:filter.attr('method'), // тип запроса
            beforeSend:function(xhr){
                filter.find('button').text('Загружаю...'); // изменяем текст кнопки
            },
            success:function(data){
                filter.find('button').text('Применить фильтр'); // возвращаеи текст кнопки
                $('#response').html(data);
            }
        });
        return false;
    });
});

3. Обработчик PHP

Ну и последний шаг. Основная задача, с которой у многих людей возникают трудности — это задание аргументов для WP_Query с учётом всех параметров фильтра выше.

function true_filter_function(){
    $args = array(
        'orderby' => 'date', // сортировка по дате у нас будет в любом случае (но вы можете изменить/доработать это)
        'order' => $_POST['date'] // ASC или DESC
    );
 
    // для таксономий
    if( isset( $_POST['categoryfilter'] )
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'category',
                'field' => 'id',
                'terms' => $_POST['categoryfilter']
            )
        );
 
    // создаём массив $args['meta_query'] если указана хотя бы одна цена или отмечен чекбокс
    if( isset( $_POST['cena_min'] ) || isset( $_POST['cena_max'] ) || ( isset( $_POST['featured_image'] ) && $_POST['featured_image'] == 'on' ) )
        $args['meta_query'] = array( 'relation'=>'AND' ); // AND значит все условия meta_query должны выполняться
 
    // условие 1: цена больше $_POST['cena_min']
    if( isset( $_POST['cena_min'] ) )
        $args['meta_query'][] = array(
            'key' => 'cena',
            'value' => $_POST['cena_min'],
            'type' => 'numeric',
            'compare' => '>'
        );
 
    // условие 2: цена меньше $_POST['cena_max']
    if( isset( $_POST['cena_max'] ) )
        $args['meta_query'][] = array(
            'key' => 'cena',
            'value' => $_POST['cena_max'],
            'type' => 'numeric',
            'compare' => '<'
        );
 
    // условие 3: миниатюра имеется
    if( isset( $_POST['featured_image'] ) && $_POST['featured_image'] == 'on' )
        $args['meta_query'][] = array(
            'key' => '_thumbnail_id',
            'compare' => 'EXISTS'
        );
 
    die();
}
 
 
add_action('wp_ajax_myfilter', 'true_filter_function'); 
add_action('wp_ajax_nopriv_myfilter', 'true_filter_function');

Если особый интерес у вас вызывают последние две строчки, то тема AJAX в WordPress подробно раскрыта тут.

Источник: misha.blog

Миша Рудрастых

Путешествует по миру и рассказывает всем о WordPress лично, у себя в блогах и на курсах в Санкт-Петербурге. Умеет просто объяснять сложные вещи, делает это красиво. Организовывает неплохие WordCamp's, но совсем не умеет слушать чужие доклады.

Добавить комментарий

%d такие блоггеры, как: