В современных проектах на WordPress часто возникает задача динамически выводить список постов с возможностью фильтрации по таксономиям, метаданным или произвольным параметрам. Это позволяет улучшить удобство пользователей и повысить функциональность сайта без установки громоздких плагинов. В этой статье подробно разберём, как с помощью кастомного кода создать динамический список постов с фильтром, используя WP_Query, AJAX и лучшие практики WordPress.
Почему стоит создавать собственный фильтр для постов
Большинство готовых плагинов с фильтрами могут быть избыточными, замедлять сайт или не подходить по дизайну и функционалу. Самостоятельная реализация позволяет:
- Оптимизировать запросы под конкретные задачи.
- Точно контролировать вывод и стили.
- Легко интегрировать с темой и другими плагинами.
- Избежать конфликтов и лишнего кода.
Кроме того, это полезный опыт для разработчиков и возможность расширять функционал без ограничений.
Создание базового WP_Query с параметрами фильтра
Начнём с простого примера: у нас есть кастомный тип постов product и таксономия product_cat. Нужно вывести список товаров, которые можно фильтровать по категориям.
Пример функции на PHP для формирования запроса:
function wpmanual_get_filtered_products($category_slug = '') {
$args = [
'post_type' => 'product',
'posts_per_page' => 10,
];
if ($category_slug) {
$args['tax_query'] = [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $category_slug,
],
];
}
$query = new WP_Query($args);
return $query;
}Функция wpmanual_get_filtered_products принимает слаг категории и возвращает объект запроса. Если слаг не передан — вернёт все товары.
Вывод списка постов в шаблоне
Теперь сделаем вывод списка товаров, используя эту функцию:
$products_query = wpmanual_get_filtered_products($_GET['category'] ?? '');
if ($products_query->have_posts()) {
echo '<ul class="wpmanual-products-list">';
while ($products_query->have_posts()) {
$products_query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
} else {
echo '<p>Товары не найдены.</p>';
}
wp_reset_postdata();Так пользователь может фильтровать товары, передавая параметр category в URL, например, ?category=smartfony.
Добавление AJAX-фильтра для динамического обновления списка
Чтобы сделать фильтр удобнее, реализуем обновление списка товаров без перезагрузки страницы с помощью AJAX.
1. JavaScript для отправки AJAX-запроса
В файл темы добавьте следующий скрипт, который отслеживает изменение фильтра и отправляет запрос:
jQuery(document).ready(function($) {
$('#wpmanual-category-filter').on('change', function() {
var category = $(this).val();
$.ajax({
url: wpmanual_ajax_object.ajax_url,
method: 'POST',
data: {
action: 'wpmanual_filter_products',
category: category,
},
success: function(response) {
$('#wpmanual-products-container').html(response);
}
});
});
});2. HTML-разметка фильтра и контейнера списка
В шаблоне добавьте селектор и контейнер для списка:
<select id="wpmanual-category-filter">
<option value="">Все категории</option>
<option value="smartfony">Смартфоны</option>
<option value="noutbuki">Ноутбуки</option>
</select>
<div id="wpmanual-products-container">
<!-- Сюда подгружаются товары -->
</div>3. PHP-обработчик AJAX-запроса
Добавьте в functions.php следующий обработчик:
add_action('wp_ajax_wpmanual_filter_products', 'wpmanual_ajax_filter_products');
add_action('wp_ajax_nopriv_wpmanual_filter_products', 'wpmanual_ajax_filter_products');
function wpmanual_ajax_filter_products() {
$category = sanitize_text_field($_POST['category'] ?? '');
$query = wpmanual_get_filtered_products($category);
if ($query->have_posts()) {
echo '<ul class="wpmanual-products-list">';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
} else {
echo '<p>Товары не найдены.</p>';
}
wp_reset_postdata();
wp_die();
}4. Подключение скрипта и локализация AJAX URL
В functions.php зарегистрируйте и подключите скрипт, чтобы передать AJAX URL:
function wpmanual_enqueue_scripts() {
wp_enqueue_script('wpmanual-filter', get_template_directory_uri() . '/js/wpmanual-filter.js', ['jquery'], '1.0', true);
wp_localize_script('wpmanual-filter', 'wpmanual_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php'),
]);
}
add_action('wp_enqueue_scripts', 'wpmanual_enqueue_scripts');Дополнительные возможности фильтрации
Фильтрация по метаполям
Если нужно фильтровать посты по произвольным полям, например, цене или рейтингу, добавьте в WP_Query параметр meta_query. Например, чтобы отобразить товары с ценой ниже 10000:
$args['meta_query'] = [
[
'key' => '_price',
'value' => 10000,
'type' => 'NUMERIC',
'compare' => '<=',
],
];Множественный выбор фильтров
Для расширения функционала добавьте несколько фильтров, например, категории и цвет. В AJAX-запросе передавайте несколько параметров, а в PHP формируйте соответствующий запрос с несколькими tax_query и meta_query.
Использование плагина Clearfy Pro для оптимизации
Для ускорения работы запросов и очистки базы можно использовать плагин Clearfy Pro, который позволяет отключать ненужные скрипты, оптимизировать запросы и управлять кэшированием.
Заключение
Создание собственного динамического списка постов с фильтром в WordPress — задача вполне выполнимая и дающая полный контроль над функционалом. Используя WP_Query и AJAX, вы можете реализовать быстрый, удобный и легковесный фильтр, сконцентрированный именно на ваших задачах. Такой подход улучшит пользовательский опыт и расширит возможности вашего сайта.