В последнее время замечаю, что всё больше постов публикуются по просьбам читателей, так что пишите, возможно и для вас разберу какую-нибудь тему 🙂
Сейчас я покажу вам, как легко и просто создавать асинхронные фильтры записей/товаров (и те и вторые — это произвольные типы постов) на сайте при помощи всего лишь 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