В этой статье разберём, как вывести на страницу WordPress список постов с возможностью фильтрации по категориям и мета-полям. Это частая задача при создании кастомных архивов, каталогов или каталогов товаров на базе WordPress. Мы рассмотрим практическое решение с примерами кода, чтобы вы могли быстро внедрить фильтрацию на своём сайте.
Зачем нужна фильтрация по категориям и мета-полям
Категории позволяют сгруппировать записи по темам, а мета-поля (custom fields) — хранить дополнительную информацию, например, цену, цвет, рейтинг и другое. Объединённая фильтрация помогает пользователям быстрее находить нужный контент.
Например, если у вас каталог товаров, можно показывать только товары из категории "Футболки" и с мета-полем "цвет" = "синий".
Используем класс WP_Query для выборки с фильтрацией
Основной инструмент для выборки записей — класс WP_Query. Для фильтрации по категориям применяется параметр category_name или tax_query, для мета-полей — meta_query.
Пример базового запроса с фильтрацией по категории и мета-полю:
function wpapp_get_filtered_posts($category_slug, $meta_key, $meta_value) {
$args = [
'post_type' => 'post',
'category_name' => $category_slug,
'meta_query' => [
[
'key' => $meta_key,
'value' => $meta_value,
'compare' => '='
]
]
];
$query = new WP_Query($args);
return $query;
}Здесь мы создаём функцию wpapp_get_filtered_posts, которая принимает слаг категории, ключ и значение мета-поля, и возвращает объект WP_Query с подходящими постами.
Выводим список постов и добавляем HTML для фильтров
Чтобы пользователь мог выбрать категорию и значение мета-поля, необходимо добавить форму фильтрации. Рассмотрим пример с выпадающими списками:
<form method="GET">
<select name="category">
<option value="">Выберите категорию</option>
<?php
$categories = get_categories();
foreach ($categories as $cat) {
$selected = (isset($_GET['category']) && $_GET['category'] === $cat->slug) ? 'selected' : '';
echo "<option value=\"{$cat->slug}\" $selected>{$cat->name}</option>";
}
?>
</select>
<select name="color">
<option value="">Выберите цвет</option>
<option value="red">Красный</option>
<option value="blue">Синий</option>
<option value="green">Зелёный</option>
</select>
<button type="submit">Фильтровать</button>
</form>При отправке формы параметры будут доступны в $_GET. Теперь подключим фильтрацию к нашему запросу:
$category = isset($_GET['category']) ? sanitize_text_field($_GET['category']) : '';
$color = isset($_GET['color']) ? sanitize_text_field($_GET['color']) : '';
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
];
if ($category) {
$args['category_name'] = $category;
}
if ($color) {
$args['meta_query'] = [
[
'key' => 'color',
'value' => $color,
'compare' => '=',
]
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
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();Расширенные возможности: фильтрация нескольких мета полей и AJAX
Фильтрация по нескольким мета-полям
Если нужно фильтровать сразу по нескольким мета-полям, используйте массив в meta_query с параметром relation:
$args['meta_query'] = [
'relation' => 'AND',
[
'key' => 'color',
'value' => $color,
'compare' => '=',
],
[
'key' => 'size',
'value' => $size,
'compare' => '=',
]
];Так вы сможете фильтровать, например, по цвету и размеру одновременно.
Добавляем AJAX фильтрацию без перезагрузки
Для улучшения UX можно сделать фильтрацию через AJAX. Это уменьшит время загрузки и сделает интерфейс живым.
Основные шаги:
- Создайте JS скрипт, который будет слушать изменения фильтров и отправлять AJAX запрос на сервер.
- Регистрируйте обработчик AJAX в WordPress через
add_action('wp_ajax_...')иadd_action('wp_ajax_nopriv_...'). - Обрабатывайте параметры, формируйте WP_Query и возвращайте HTML с постами.
- В JS вставляйте полученный HTML в нужный блок.
Пример JS (jQuery):
jQuery(document).ready(function($) {
$('#filter-form select').on('change', function() {
var data = {
action: 'wpapp_filter_posts',
category: $('#filter-category').val(),
color: $('#filter-color').val(),
};
$.post(wpapp_ajax_object.ajax_url, data, function(response) {
$('#posts-container').html(response);
});
});
});PHP обработчик:
add_action('wp_ajax_wpapp_filter_posts', 'wpapp_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpapp_filter_posts', 'wpapp_ajax_filter_posts');
function wpapp_ajax_filter_posts() {
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$color = isset($_POST['color']) ? sanitize_text_field($_POST['color']) : '';
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
];
if ($category) {
$args['category_name'] = $category;
}
if ($color) {
$args['meta_query'] = [
[
'key' => 'color',
'value' => $color,
'compare' => '=',
]
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
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();
}Не забудьте локализовать скрипт, чтобы передать ajax_url:
wp_enqueue_script('wpapp-filter', get_template_directory_uri() . '/js/filter.js', ['jquery'], null, true);
wp_localize_script('wpapp-filter', 'wpapp_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php'),
]);Использование готовых плагинов для расширенной фильтрации
Если не хочется писать код самостоятельно, можно использовать плагины:
- Clearfy Pro — расширяет стандартные функции WordPress, в том числе улучшает работу с запросами и фильтрацией.
- Плагин FacetWP — мощный инструмент для создания AJAX-фильтров по таксономиям и мета-полям.
- Плагин Search & Filter — простой в использовании фильтр с настройками для категорий и кастомных полей.
Для интеграции с WPShop и дополнительной кастомизации рекомендуем посмотреть официальный сайт WPShop.
Выводы и рекомендации
Фильтрация постов по категориям и мета-полям — важный инструмент для удобства пользователей и повышения конверсии. Для простых задач достаточно WP_Query с параметрами category_name и meta_query. Для более сложных — стоит использовать AJAX и готовые плагины.
Обязательно фильтруйте и валидируйте входящие данные, чтобы избежать ошибок и уязвимостей.