Зачем нужны динамические фильтры в теме WordPress
Если вы работаете с кастомными типами записей (Custom Post Types, CPT) в WordPress, часто возникает задача предоставить пользователю удобный способ отфильтровать записи по определённым параметрам: таксономиям, метаполям, датам и другим атрибутам. Это особенно актуально для тем, где контент разнообразен и должен быстро находиться посетителями.
Динамические фильтры позволяют улучшить UX, сократить время поиска нужной информации и сделать сайт более интерактивным без необходимости установки тяжеловесных плагинов. В этой статье мы рассмотрим, как реализовать такие фильтры в теме WordPress с примерами кода и разбором возможных сложностей.
Подготовка: регистрация кастомного типа записей и таксономий
Для начала предположим, что у вас есть кастомный тип записей portfolio и две таксономии: project_type (тип проекта) и technology (технология). Если вы еще не зарегистрировали их, вот пример регистрации в файле functions.php вашей темы:
function wp_theme_register_cpt_and_taxonomies() {
// Регистрируем кастомный тип записей
register_post_type('portfolio', [
'labels' => [
'name' => 'Портфолио',
'singular_name' => 'Проект',
],
'public' => true,
'has_archive' => true,
'rewrite' => ['slug' => 'portfolio'],
'supports' => ['title', 'editor', 'thumbnail'],
'show_in_rest' => true // для поддержки Gutenberg
]);
// Регистрируем таксономию project_type
register_taxonomy('project_type', 'portfolio', [
'labels' => [
'name' => 'Типы проектов',
'singular_name' => 'Тип проекта',
],
'hierarchical' => true,
'show_in_rest' => true,
'rewrite' => ['slug' => 'project-type']
]);
// Регистрируем таксономию technology
register_taxonomy('technology', 'portfolio', [
'labels' => [
'name' => 'Технологии',
'singular_name' => 'Технология',
],
'hierarchical' => false,
'show_in_rest' => true,
'rewrite' => ['slug' => 'technology']
]);
}
add_action('init', 'wp_theme_register_cpt_and_taxonomies');Этот код гарантирует, что у вас есть все необходимое для фильтрации по таксономиям.
Создание формы динамических фильтров в шаблоне темы
Далее создадим форму, которая выведет все доступные термины таксономий для выбора пользователем. Для удобства реализуем это в файле шаблона, например, archive-portfolio.php или отдельном шаблоне страницы.
Пример формы с фильтрами:
<form method="GET" action="">
<div class="filter-group">
<label for="project_type">Тип проекта:</label>
<select name="project_type" id="project_type">
<option value="">Все</option>
<?php
$project_types = get_terms(['taxonomy' => 'project_type', 'hide_empty' => true]);
foreach ($project_types as $term) {
$selected = (isset($_GET['project_type']) && $_GET['project_type'] === $term->slug) ? 'selected' : '';
echo "<option value='{$term->slug}' $selected>{$term->name}</option>";
}
?>
</select>
</div>
<div class="filter-group">
<label for="technology">Технология:</label>
<select name="technology" id="technology">
<option value="">Все</option>
<?php
$technologies = get_terms(['taxonomy' => 'technology', 'hide_empty' => true]);
foreach ($technologies as $term) {
$selected = (isset($_GET['technology']) && $_GET['technology'] === $term->slug) ? 'selected' : '';
echo "<option value='{$term->slug}' $selected>{$term->name}</option>";
}
?>
</select>
</div>
<button type="submit">Фильтровать</button>
</form>Здесь мы выводим два выпадающих списка, которые при отправке передают параметры в URL, например ?project_type=web&technology=php.
Обработка фильтров и вывод результатов
Чтобы фильтровать записи, нужно изменить запрос WordPress. Для этого в файле шаблона или через хуки (например, pre_get_posts) добавим логику для фильтрации.
Пример обработки в archive-portfolio.php:
$args = [
'post_type' => 'portfolio',
'posts_per_page' => 10,
];
// Массив для таксономий
$tax_query = [];
if (!empty($_GET['project_type'])) {
$tax_query[] = [
'taxonomy' => 'project_type',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['project_type'])
];
}
if (!empty($_GET['technology'])) {
$tax_query[] = [
'taxonomy' => 'technology',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['technology'])
];
}
if (!empty($tax_query)) {
// Если несколько фильтров, объединяем логикой AND
$args['tax_query'] = ['relation' => 'AND'] + $tax_query;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
?>
<article id="post-<?php the_ID(); ?>" class="portfolio-item">
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div class="entry-summary"><?php the_excerpt(); ?></div>
</article>
<?php
}
wp_reset_postdata();
} else {
echo '<p>Проекты не найдены.</p>';
}Этот код строит запрос с учетом выбранных фильтров и выводит результаты.
Добавление фильтра по метаполю с примером кода
Иногда нужно фильтровать записи не только по таксономиям, но и по метаполям (Custom Fields). Например, у вас есть метаполе project_budget и вы хотите отфильтровать проекты с бюджетом менее 100000.
Расширим логику запроса:
if (!empty($_GET['max_budget'])) {
$max_budget = intval($_GET['max_budget']);
$args['meta_query'][] = [
'key' => 'project_budget',
'value' => $max_budget,
'type' => 'NUMERIC',
'compare' => '<='
];
}Добавим в форму соответствующее поле:
<div class="filter-group">
<label for="max_budget">Максимальный бюджет:</label>
<input type="number" name="max_budget" id="max_budget" value="<?php echo isset($_GET['max_budget']) ? intval($_GET['max_budget']) : ''; ?>" />
</div>Теперь пользователь может фильтровать проекты и по бюджету, что расширяет возможности поиска.
Советы по оптимизации и UX для динамических фильтров
Фильтрация по нескольким параметрам может значительно увеличить нагрузку на базу данных, особенно если у вас большой каталог. Чтобы этого избежать:
- Используйте индексацию метаполей в базе данных.
- Кешируйте результаты с помощью Transients API или плагинов кеширования.
- Добавьте AJAX-запросы для динамической подгрузки без перезагрузки страницы — это улучшит UX.
- Используйте удобные UI-элементы: чекбоксы, слайдеры для числовых значений и автозаполнение для тегов.
Для реализации AJAX можно подключить скрипты и обработчики в теме, используя стандартные WordPress-хуки wp_ajax_ и wp_ajax_nopriv_. Это позволит динамически обновлять список проектов при смене фильтра.
Пример AJAX-фильтрации с использованием WP AJAX API
Добавим пример JS-кода для отправки данных фильтрации и обновления результатов:
jQuery(document).ready(function($) {
$('#filter-form select, #filter-form input').on('change', function() {
var data = $('#filter-form').serialize();
$.ajax({
url: wp_theme_ajax_object.ajax_url,
type: 'GET',
data: data + '&action=wp_theme_filter_portfolio',
success: function(response) {
$('#portfolio-results').html(response);
}
});
});
});И в functions.php добавим обработчик:
function wp_theme_filter_portfolio_callback() {
$args = [
'post_type' => 'portfolio',
'posts_per_page' => 10,
];
$tax_query = [];
if (!empty($_GET['project_type'])) {
$tax_query[] = [
'taxonomy' => 'project_type',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['project_type'])
];
}
if (!empty($_GET['technology'])) {
$tax_query[] = [
'taxonomy' => 'technology',
'field' => 'slug',
'terms' => sanitize_text_field($_GET['technology'])
];
}
if (!empty($tax_query)) {
$args['tax_query'] = ['relation' => 'AND'] + $tax_query;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
echo '<article class="portfolio-item">';
echo '<h2><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
echo '<div>' . get_the_excerpt() . '</div>';
echo '</article>';
}
wp_reset_postdata();
} else {
echo '<p>Проекты не найдены.</p>';
}
wp_die();
}
add_action('wp_ajax_wp_theme_filter_portfolio', 'wp_theme_filter_portfolio_callback');
add_action('wp_ajax_nopriv_wp_theme_filter_portfolio', 'wp_theme_filter_portfolio_callback');Не забудьте локализовать скрипты и передать ajax_url через wp_localize_script.
Использование плагина Clearfy Pro для оптимизации фильтров
Если вы используете тему с поддержкой плагина Clearfy Pro, то он поможет оптимизировать запросы, убрать лишние запросы к базе и ускорить работу фильтров. Это особенно полезно при большом количестве метаполей и таксономий.
Clearfy Pro имеет встроенные возможности для управления индексами и кеширования метаполей, что существенно повышает производительность фильтров.