Иногда стандартных возможностей WordPress для вывода записей по определённым параметрам бывает недостаточно, особенно когда нужно создать сложный фильтр, который учитывает несколько условий одновременно. В этой статье мы разберём, как создать уникальный фильтр для записей WordPress, который позволит выводить контент по нескольким параметрам — категориям, меткам, пользовательским полям и таксономиям, а также добавим возможность динамической подгрузки результатов.
Почему стандартный WP_Query не всегда решает задачи фильтрации
WP_Query — мощный инструмент для выборки записей, но если вы хотите сделать фильтр с несколькими независимыми параметрами, то код быстро становится громоздким и трудно сопровождаемым. Например, когда нужно фильтровать записи одновременно по нескольким категориям, пользовательским полям (meta_query) и пользовательским таксономиям, нужно аккуратно строить массивы параметров и правильно комбинировать операторы.
Кроме того, если фильтр предполагает динамическое обновление результатов на фронтенде (без перезагрузки страницы), понадобится AJAX, а значит, нужно продумать обработку запросов и безопасность.
Пошаговое создание уникального фильтра для записей WordPress
1. Определяем параметры фильтрации
Для примера возьмём фильтр по следующим параметрам:
- Категории записей (tax_query по категории)
- Произвольные поля (meta_query, например, цена или рейтинг)
- Таксономии (например, по тегам или кастомной таксономии)
Наша задача — сформировать WP_Query, который гибко комбинирует эти параметры.
2. Формируем аргументы WP_Query с динамическими параметрами
Создадим функцию wpdeveloper_get_filtered_posts_args, которая принимает массив параметров и возвращает аргументы для WP_Query:
function wpdeveloper_get_filtered_posts_args($filters) {
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'tax_query' => [],
'meta_query' => [],
'relation' => 'AND',
];
// Фильтрация по категориям
if (!empty($filters['categories'])) {
$args['tax_query'][] = [
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $filters['categories'],
'operator' => 'IN',
];
}
// Фильтрация по пользовательским таксономиям
if (!empty($filters['custom_tax'])) {
foreach ($filters['custom_tax'] as $taxonomy => $terms) {
$args['tax_query'][] = [
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $terms,
'operator' => 'IN',
];
}
}
// Фильтрация по метаполям
if (!empty($filters['meta_query'])) {
foreach ($filters['meta_query'] as $meta) {
$args['meta_query'][] = $meta;
}
}
// Если есть несколько условий таксономий добавляем relation
if (count($args['tax_query']) > 1) {
$args['tax_query']['relation'] = 'AND';
}
return $args;
}
В этой функции мы аккуратно формируем массив аргументов, учитывая разные типы фильтров.
3. Пример параметров фильтра и запрос
Вот пример массива фильтров, который мы можем получить из формы на сайте:
$filters = [
'categories' => [12, 34], // ID категорий
'custom_tax' => [
'genre' => ['comedy', 'drama'],
'year' => ['2023'],
],
'meta_query' => [
[
'key' => 'price',
'value' => [100, 500],
'type' => 'numeric',
'compare' => 'BETWEEN'
],
[
'key' => 'rating',
'value' => 4,
'type' => 'numeric',
'compare' => '>='
]
]
];
$args = wpdeveloper_get_filtered_posts_args($filters);
$query = new WP_Query($args);
Такой запрос выведет записи из категорий с ID 12 и 34, с жанром комедия или драма, годом 2023 и ценой от 100 до 500, рейтингом 4 и выше.
Добавляем AJAX для динамической подгрузки фильтра
1. Регистрация обработчика AJAX в functions.php
Чтобы обновлять результаты без перезагрузки страницы, используем AJAX. В файле functions.php темы или в плагине добавим:
add_action('wp_ajax_wpdeveloper_filter_posts', 'wpdeveloper_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpdeveloper_filter_posts', 'wpdeveloper_ajax_filter_posts');
function wpdeveloper_ajax_filter_posts() {
// Проверяем nonce для безопасности
check_ajax_referer('wpdeveloper_filter_nonce', 'nonce');
$filters = isset($_POST['filters']) ? $_POST['filters'] : [];
$args = wpdeveloper_get_filtered_posts_args($filters);
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
while ($query->have_posts()) {
$query->the_post();
// Рендерим шаблон для записи, например content-excerpt.php
get_template_part('template-parts/content', 'excerpt');
}
wp_send_json_success(ob_get_clean());
} else {
wp_send_json_error('Записей не найдено');
}
wp_die();
}
Этот обработчик получает фильтры, формирует запрос и возвращает HTML списка записей.
2. JavaScript для отправки AJAX-запроса
В шаблоне подключаем JS, который собирает параметры и отправляет запрос:
jQuery(document).ready(function($) {
$('#filter-form').on('submit', function(e) {
e.preventDefault();
var filters = {
categories: $('#categories-select').val(),
custom_tax: {
genre: $('#genre-select').val(),
year: $('#year-select').val()
},
meta_query: [
{
key: 'price',
value: [$('#price-min').val(), $('#price-max').val()],
type: 'numeric',
compare: 'BETWEEN'
},
{
key: 'rating',
value: $('#rating-min').val(),
type: 'numeric',
compare: '>='
}
]
};
$.ajax({
url: wpdeveloper_ajax_object.ajax_url,
type: 'POST',
data: {
action: 'wpdeveloper_filter_posts',
filters: filters,
nonce: wpdeveloper_ajax_object.nonce
},
success: function(response) {
if (response.success) {
$('#posts-container').html(response.data);
} else {
$('#posts-container').html('<p>Записей не найдено</p>');
}
},
error: function() {
$('#posts-container').html('<p>Ошибка загрузки данных</p>');
}
});
});
});
Не забудьте локализовать скрипт в PHP:
wp_enqueue_script('wpdeveloper-filter', get_template_directory_uri() . '/js/filter.js', ['jquery'], null, true);
wp_localize_script('wpdeveloper-filter', 'wpdeveloper_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdeveloper_filter_nonce')
]);
Советы по улучшению и расширению фильтра
Чтобы сделать фильтр ещё удобнее и эффективнее, стоит:
- Добавить пагинацию с AJAX, чтобы подгружать больше записей без перезагрузки.
- Кэшировать результаты запросов для снижения нагрузки.
- Использовать пользовательские шаблоны для вывода записей в зависимости от типа контента.
- Реализовать поддержку сортировки по дате, популярности, рейтингу и другим метаполям.
- При большом количестве условий фильтра учитывать особенности производительности запросов и оптимизировать индексы базы данных.
Интеграция с плагином Clearfy Pro для оптимизации фильтров
Если вы используете Clearfy Pro, он поможет оптимизировать работу сайта и фильтров, отключая лишние скрипты и улучшая производительность. Это особенно полезно, если ваш фильтр использует много AJAX-запросов и сложные meta_query.
Вывод
Создание уникального фильтра для записей WordPress с несколькими параметрами — задача вполне выполнимая, если правильно сформировать запросы и добавить AJAX для динамического обновления. Такой подход значительно улучшит пользовательский опыт на сайте и позволит гибко управлять выводом контента.