В условиях растущего количества контента на сайте часто возникает необходимость предоставить пользователям удобный инструмент для фильтрации записей по различным атрибутам. Особенно это актуально для кастомных типов постов (Custom Post Types), где стандартные возможности WordPress для фильтрации ограничены. В этой статье мы подробно рассмотрим, как создать динамический фильтр по атрибутам для кастомных постов с помощью кода и популярных плагинов.
Что такое динамический фильтр и зачем он нужен
Динамический фильтр — это интерфейс на сайте, который позволяет пользователю выбирать параметры (атрибуты), а система автоматически подбирает и отображает записи, соответствующие выбранным критериям. Такой фильтр особенно полезен для каталогов, портфолио, интернет-магазинов и других проектов с большим количеством записей.
Если у вас, например, кастомный тип поста «Продукты», вы можете фильтровать их по атрибутам: цвет, размер, цена, бренд и т.д. Для реализации такого функционала в WordPress потребуется работа с таксономиями, мета-полями и запросами WP_Query.
Использование пользовательских таксономий для фильтрации
Первый шаг — убедиться, что у вашего кастомного типа поста есть таксономии, которые будут выступать в роли атрибутов фильтрации. Если таксономий нет, их нужно зарегистрировать. Вот пример регистрации таксономии «Цвет» для кастомного типа «product»:
function wpto_register_taxonomy_color() {
register_taxonomy('color', 'product', array(
'label' => 'Цвет',
'hierarchical' => true,
'show_ui' => true,
'rewrite' => array('slug' => 'color'),
));
}
add_action('init', 'wpto_register_taxonomy_color');Аналогично можно зарегистрировать таксономии «Бренд», «Размер» и другие.
После этого в админке WordPress при добавлении или редактировании записи типа «product» появятся поля выбора значений этих таксономий.
Вывод таксономий в форме фильтрации
Создадим форму фильтрации, которая будет динамически выводить все доступные термины таксономии «color»:
function wpto_show_filter_form() {
$colors = get_terms(array(
'taxonomy' => 'color',
'hide_empty' => false,
));
if (!empty($colors) && !is_wp_error($colors)) {
echo '<form method="GET" id="wpto-filter-form">';
echo '<select name="color" onchange="this.form.submit()">';
echo '<option value="">Все цвета</option>';
foreach ($colors as $color) {
$selected = (isset($_GET['color']) && $_GET['color'] == $color->slug) ? 'selected' : '';
echo '<option value="' . esc_attr($color->slug) . '" ' . $selected . '>' . esc_html($color->name) . '</option>';
}
echo '</select>';
echo '</form>';
}
}Эту функцию можно вызвать в нужном месте шаблона, чтобы вывести фильтр по цветам.
Обработка фильтра и настройка WP_Query
Чтобы фильтр работал, нужно изменить основной запрос так, чтобы он учитывал выбранные значения таксономий. Для этого есть несколько способов, например, фильтр pre_get_posts. Ниже пример кода, который отфильтрует кастомные посты «product» по выбранному цвету:
function wpto_filter_products_query($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
if (!empty($_GET['color'])) {
$color = sanitize_text_field($_GET['color']);
$tax_query = array(
array(
'taxonomy' => 'color',
'field' => 'slug',
'terms' => $color,
),
);
$query->set('tax_query', $tax_query);
}
}
}
add_action('pre_get_posts', 'wpto_filter_products_query');Таким образом, при выборе цвета и отправке формы на странице архива продуктов будут отображаться только записи с выбранным цветом.
Поддержка нескольких атрибутов и сложных условий
Для фильтрации по нескольким таксономиям добавьте несколько элементов в массив tax_query с параметром 'relation' => 'AND'. Например:
function wpto_filter_products_multiple($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
$tax_query = array('relation' => 'AND');
if (!empty($_GET['color'])) {
$tax_query[] = array(
'taxonomy' => 'color',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['color']),
);
}
if (!empty($_GET['brand'])) {
$tax_query[] = array(
'taxonomy' => 'brand',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['brand']),
);
}
if (count($tax_query) > 1) {
$query->set('tax_query', $tax_query);
}
}
}
add_action('pre_get_posts', 'wpto_filter_products_multiple');Так можно создавать сложные фильтры с несколькими параметрами.
Фильтрация по мета-полям (кастомным полям)
Если атрибуты записаны в мета-полях, фильтрация реализуется через параметр meta_query в WP_Query. Например, фильтр по цене (числовое поле):
function wpto_filter_products_by_price($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
$meta_query = array();
if (!empty($_GET['min_price'])) {
$meta_query[] = array(
'key' => 'price',
'value' => (int) $_GET['min_price'],
'compare' => '>=',
'type' => 'NUMERIC',
);
}
if (!empty($_GET['max_price'])) {
$meta_query[] = array(
'key' => 'price',
'value' => (int) $_GET['max_price'],
'compare' => '<=',
'type' => 'NUMERIC',
);
}
if ($meta_query) {
$query->set('meta_query', $meta_query);
}
}
}
add_action('pre_get_posts', 'wpto_filter_products_by_price');Для удобства пользователей можно добавить поля ввода минимальной и максимальной цены в форму фильтра.
Рекомендуемые плагины для динамической фильтрации
Если вы не хотите писать весь функционал с нуля, можно использовать готовые решения:
- Clearfy Pro — содержит модуль оптимизации запросов и фильтров, упрощает настройку.
- WPRemark — плагин с функциями расширенной фильтрации и сортировки кастомных постов.
- FacetWP (платный) — мощный инструмент для создания динамических фильтров с Ajax, поддерживает кастомные поля и таксономии.
Оптимизация и UX фильтра
Важно, чтобы фильтр не замедлял работу сайта. Для этого:
- Используйте Ajax-подгрузку результатов, чтобы не обновлять всю страницу.
- Кэшируйте результаты запросов, особенно при большом объеме данных.
- Добавьте кнопку «Сбросить фильтр» для удобства пользователей.
- Используйте понятные и компактные элементы формы: чекбоксы, слайдеры, выпадающие списки.
Пример Ajax-подгрузки фильтра можно реализовать через wp_ajax хуки и JavaScript. Это повышает интерактивность и удобство.
Пример простого Ajax-фильтра по цвету
Фронтенд (JavaScript):
document.getElementById('wpto-filter-form').addEventListener('change', function(e) {
e.preventDefault();
var color = this.color.value;
var data = new FormData();
data.append('action', 'wpto_filter_products_ajax');
data.append('color', color);
fetch(wpto_ajax_url, {
method: 'POST',
credentials: 'same-origin',
body: data
})
.then(response => response.text())
.then(html => {
document.getElementById('wpto-products-list').innerHTML = html;
});
});PHP (обработка Ajax):
function wpto_filter_products_ajax() {
$color = sanitize_text_field($_POST['color']);
$args = array(
'post_type' => 'product',
'posts_per_page' => 10,
);
if ($color) {
$args['tax_query'] = array(
array(
'taxonomy' => 'color',
'field' => 'slug',
'terms' => $color,
),
);
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<div>' . get_the_title() . '</div>';
}
} else {
echo '<p>Нет продуктов по заданным параметрам.</p>';
}
wp_die();
}
add_action('wp_ajax_wpto_filter_products_ajax', 'wpto_filter_products_ajax');
add_action('wp_ajax_nopriv_wpto_filter_products_ajax', 'wpto_filter_products_ajax');Не забудьте локализовать переменную wpto_ajax_url с помощью wp_localize_script.
Итоги
Создание динамического фильтра по атрибутам для кастомных постов в WordPress — задача вполне решаемая с помощью пользовательских таксономий, мета-запросов и корректной настройки WP_Query. Это повышает удобство пользователей и качество сайта.
Для упрощения можно использовать готовые плагины, например, Clearfy Pro и WPRemark, которые помогут оптимизировать и расширить функционал фильтрации.
Если вы хотите сделать фильтр максимально интерактивным, рекомендуем реализовать Ajax-подгрузку результатов.