Что такое динамическая фильтровая форма и зачем она нужна в теме WordPress
Динамическая фильтровая форма — это инструмент, позволяющий пользователям сайта быстро и удобно выбирать записи по нескольким параметрам одновременно. В тематике WordPress это особенно актуально при работе с кастомными типами записей, такими как товары, портфолио, отзывы или события. Вместо того чтобы вручную создавать множество предопределённых страниц с фильтрами, мы даём пользователю возможность интерактивно настроить вывод.
Основная задача — сделать интерфейс фильтрации удобным, а логику — максимально оптимизированной и гибкой. Такой фильтр должен подгружать результаты без перезагрузки страницы или с минимальной задержкой, использовать стандартные механизмы WordPress и поддерживать кастомные поля и таксономии.
В этой статье я расскажу, как создать динамическую фильтровую форму в теме WordPress с примерами кода и рекомендациями по использованию популярных плагинов для расширения функционала.
Подготовка темы для динамического фильтра: регистрация кастомных таксономий и полей
Перед тем, как реализовывать фильтр, нужно убедиться, что у нас есть данные, по которым мы будем фильтровать. Например, если у вас есть кастомный тип записи product с таксономиями brand и color, а также произвольным полем price, то фильтр должен учитывать все эти параметры.
Вот пример регистрации таксономий для темы wp_theme_filter_register_taxonomies:
function wp_theme_filter_register_taxonomies() {
register_taxonomy('brand', 'product', [
'label' => 'Бренд',
'hierarchical' => true,
'public' => true,
'rewrite' => ['slug' => 'brand'],
]);
register_taxonomy('color', 'product', [
'label' => 'Цвет',
'hierarchical' => false,
'public' => true,
'rewrite' => ['slug' => 'color'],
]);
}
add_action('init', 'wp_theme_filter_register_taxonomies');Также используйте поле price через Custom Fields API или Advanced Custom Fields (ACF). Важно, чтобы поле было числовым для корректной фильтрации.
Создание HTML формы фильтра с динамическими параметрами
Форма фильтра должна подтягивать значения таксономий и диапазон цен автоматически. Для этого используем функции WordPress:
get_terms()— для получения списка терминов таксономий;get_post_meta()— для работы с пользовательскими полями.
Пример формы с чекбоксами для брендов и цветов, а также диапазоном цены:
<form id="wp_theme_filter_form" method="GET">
<h3>Фильтр товаров</h3>
<div class="filter-group">
<h4>Бренд</h4>
<?php
$brands = get_terms(['taxonomy' => 'brand', 'hide_empty' => true]);
foreach ($brands as $brand) {
echo '<label><input type="checkbox" name="brand[]" value="' . esc_attr($brand->slug) . '">' . esc_html($brand->name) . '</label><br>';
}
?>
</div>
<div class="filter-group">
<h4>Цвет</h4>
<?php
$colors = get_terms(['taxonomy' => 'color', 'hide_empty' => true]);
foreach ($colors as $color) {
echo '<label><input type="checkbox" name="color[]" value="' . esc_attr($color->slug) . '">' . esc_html($color->name) . '</label><br>';
}
?>
</div>
<div class="filter-group">
<h4>Цена</h4>
<label>От: <input type="number" name="price_min" min="0"></label>
<label>До: <input type="number" name="price_max" min="0"></label>
</div>
<button type="submit">Применить</button>
</form>Форма отправляет GET-запрос, который мы затем обработаем для вывода отфильтрованных записей.
Обработка фильтра на PHP: кастомный WP_Query с фильтрами таксономий и метаполей
Далее создаём функцию для формирования запроса с учётом выбранных параметров. Назовём её wp_theme_filter_get_filtered_products:
function wp_theme_filter_get_filtered_products() {
$tax_query = [];
if (!empty($_GET['brand'])) {
$tax_query[] = [
'taxonomy' => 'brand',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', (array) $_GET['brand']),
'operator' => 'IN',
];
}
if (!empty($_GET['color'])) {
$tax_query[] = [
'taxonomy' => 'color',
'field' => 'slug',
'terms' => array_map('sanitize_text_field', (array) $_GET['color']),
'operator' => 'IN',
];
}
if (count($tax_query) > 1) {
$tax_query['relation'] = 'AND';
}
$meta_query = [];
$price_min = isset($_GET['price_min']) ? floatval($_GET['price_min']) : 0;
$price_max = isset($_GET['price_max']) ? floatval($_GET['price_max']) : 0;
if ($price_min > 0 || $price_max > 0) {
$price_filter = ['key' => 'price', 'type' => 'NUMERIC'];
if ($price_min > 0 && $price_max > 0) {
$price_filter['value'] = [$price_min, $price_max];
$price_filter['compare'] = 'BETWEEN';
} elseif ($price_min > 0) {
$price_filter['value'] = $price_min;
$price_filter['compare'] = '>=';
} elseif ($price_max > 0) {
$price_filter['value'] = $price_max;
$price_filter['compare'] = '<=';
}
$meta_query[] = $price_filter;
}
$args = [
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => $tax_query,
'meta_query' => $meta_query,
];
$query = new WP_Query($args);
return $query;
}Эта функция возвращает объекты записей, соответствующих выбранным фильтрам.
Вывод результатов и AJAX-подгрузка для улучшения UX
Для плавной работы фильтра рекомендуется использовать AJAX, чтобы обновлять список товаров без перезагрузки страницы. Основная идея:
- Подключить JavaScript, который будет отправлять данные формы через AJAX на сервер.
- Обработать AJAX-запрос в PHP, вызвав
wp_theme_filter_get_filtered_productsи сформировав HTML. - Вернуть HTML и заменить содержимое блока с товарами на странице.
Пример простого AJAX-обработчика на PHP:
add_action('wp_ajax_wp_theme_filter_ajax', 'wp_theme_filter_ajax_handler');
add_action('wp_ajax_nopriv_wp_theme_filter_ajax', 'wp_theme_filter_ajax_handler');
function wp_theme_filter_ajax_handler() {
$query = wp_theme_filter_get_filtered_products();
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
// Для примера выводим заголовок
echo '<div class="product-item">' . get_the_title() . '</div>';
}
wp_reset_postdata();
} else {
echo '<p>Товары не найдены</p>';
}
wp_die();
}JavaScript для отправки формы:
document.getElementById('wp_theme_filter_form').addEventListener('submit', function(e) {
e.preventDefault();
var formData = new FormData(this);
fetch('<?php echo admin_url('admin-ajax.php'); ?>?action=wp_theme_filter_ajax', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(html => {
document.getElementById('products-container').innerHTML = html;
});
});<Обязательно добавьте блок с id products-container для вывода результатов.
Использование плагинов для расширения возможностей фильтрации
Если писать фильтр с нуля кажется сложным, можно использовать плагины с поддержкой AJAX фильтров и кастомных типов записей:
- Clearfy Pro — оптимизация и расширение функционала, включая фильтры;
- ABC Pagination — удобная пагинация для фильтров;
- FacetWP (платный) — мощный инструмент для фильтрации с AJAX;
- Filter Everything — бесплатный плагин с широкими возможностями.
Комбинируя собственный код с возможностями плагинов, вы получите гибкую и удобную систему фильтрации для своей темы.
Оптимизация и рекомендации при создании фильтров в теме WordPress
При работе с фильтрами важно помнить об оптимизации запросов. Старайтесь минимизировать нагрузку на базу данных, используйте кэширование, например, через Transients API или сторонние плагины кэширования.
Также будьте внимательны с безопасностью: всегда фильтруйте и проверяйте входящие данные, чтобы избежать SQL-инъекций и XSS.
Для удобства пользователей добавьте индикаторы загрузки при AJAX-запросах и возможность сброса фильтров.
И наконец, протестируйте фильтр на разных устройствах и браузерах, чтобы обеспечить корректную работу.