Динамический фильтр записей — востребованная функция для сайтов на WordPress, которая позволяет пользователям быстро находить нужный контент по различным параметрам, например, по категориям, меткам, произвольным полям. В этой статье мы подробно разберём, как реализовать такой фильтр самостоятельно, без использования дополнительных плагинов, что даёт полный контроль над функционалом и производительностью.
Зачем создавать динамический фильтр без плагинов
Плагины для фильтрации контента удобны, но часто нагружают сайт, добавляют лишний код и могут конфликтовать с другими расширениями. Кроме того, собственная реализация позволяет тонко настроить логику фильтрации, внешний вид и интеграцию с темой. Это особенно важно для проектов с уникальными требованиями или ограниченным бюджетом.
В нашем примере мы создадим фильтр по категориям и кастомному полю (например, «Цена»), который будет работать без перезагрузки страницы с помощью AJAX.
Подготовка: структура и функции для выборки записей
Для начала нам понадобится функция, которая будет принимать параметры фильтра и возвращать подходящие записи. В WordPress это удобно делать через WP_Query.
Создадим функцию wpelement_get_filtered_posts в файле functions.php вашей темы:
function wpelement_get_filtered_posts($category = '', $price_min = 0, $price_max = 0) {
$meta_query = [];
if ($price_min > 0 || $price_max > 0) {
$range = [];
if ($price_min > 0) $range['>='] = $price_min;
if ($price_max > 0) $range['<='] = $price_max;
$meta_query[] = [
'key' => 'price',
'value' => [$price_min, $price_max],
'compare' => 'BETWEEN',
'type' => 'NUMERIC'
];
}
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
];
if (!empty($category)) {
$args['category_name'] = sanitize_text_field($category);
}
if (!empty($meta_query)) {
$args['meta_query'] = $meta_query;
}
$query = new WP_Query($args);
return $query;
}
Здесь мы фильтруем записи по категории и по метаполю «price» в диапазоне от $price_min до $price_max.
Создание пользовательской формы фильтрации
Далее создадим форму, с помощью которой посетители смогут выбирать параметры фильтрации. Например, фильтр по категориям и ценовому диапазону.
Добавьте этот HTML в нужное место шаблона (например, в файл archive.php или отдельный шаблон):
<form id="wpelement-filter-form">
<label>Категория:</label>
<select name="category" id="wpelement-category">
<option value="">Все категории</option>
<?php
$categories = get_categories();
foreach ($categories as $cat) {
echo '<option value="' . esc_attr($cat->slug) . '">' . esc_html($cat->name) . '</option>';
}
?>
</select>
<label>Цена от:</label>
<input type="number" name="price_min" id="wpelement-price-min" min="0" placeholder="0" />
<label>до:</label>
<input type="number" name="price_max" id="wpelement-price-max" min="0" placeholder="10000" />
<button type="submit">Применить</button>
</form>
<div id="wpelement-filter-results"></div>
Форма содержит выпадающий список с категориями и два поля ввода для ценового диапазона.
AJAX-обработка фильтрации: динамическое обновление результатов
Чтобы не перезагружать страницу, реализуем AJAX-запрос, который будет при отправке формы запрашивать отфильтрованные записи и выводить их в блок #wpelement-filter-results.
Для этого добавим JavaScript в тему (лучше через enqueue):
jQuery(document).ready(function($) {
$('#wpelement-filter-form').on('submit', function(e) {
e.preventDefault();
var data = {
action: 'wpelement_filter_posts',
category: $('#wpelement-category').val(),
price_min: $('#wpelement-price-min').val(),
price_max: $('#wpelement-price-max').val(),
nonce: wpelement_ajax.nonce
};
$.post(wpelement_ajax.url, data, function(response) {
if(response.success) {
$('#wpelement-filter-results').html(response.data);
} else {
$('#wpelement-filter-results').html('<p>Ошибка при загрузке данных.</p>');
}
});
});
});
Подключите скрипт и передайте параметры AJAX в functions.php:
function wpelement_enqueue_scripts() {
wp_enqueue_script('wpelement-filter', get_template_directory_uri() . '/js/wpelement-filter.js', ['jquery'], null, true);
wp_localize_script('wpelement-filter', 'wpelement_ajax', [
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpelement_nonce')
]);
}
add_action('wp_enqueue_scripts', 'wpelement_enqueue_scripts');
Обработка AJAX-запроса на сервере
В functions.php добавим обработчик:
function wpelement_ajax_filter_posts() {
check_ajax_referer('wpelement_nonce', 'nonce');
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$price_min = isset($_POST['price_min']) ? intval($_POST['price_min']) : 0;
$price_max = isset($_POST['price_max']) ? intval($_POST['price_max']) : 0;
$query = wpelement_get_filtered_posts($category, $price_min, $price_max);
if ($query->have_posts()) {
ob_start();
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
echo '</ul>';
wp_reset_postdata();
$result = ob_get_clean();
wp_send_json_success($result);
} else {
wp_send_json_success('<p>По вашему запросу ничего не найдено.</p>');
}
}
add_action('wp_ajax_wpelement_filter_posts', 'wpelement_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpelement_filter_posts', 'wpelement_ajax_filter_posts');
Обработчик получает данные из AJAX, выполняет запрос и возвращает HTML с результатами.
Оптимизация и расширение фильтра
Для реальных проектов можно добавить пагинацию, дополнительные параметры фильтрации (например, по дате или автору), а также кэширование результатов для уменьшения нагрузки.
Также полезно оформить вывод в виде карточек с миниатюрами и кратким описанием, чтобы улучшить UX.
Пример вывода с картинками и описанием
while ($query->have_posts()) {
$query->the_post();
echo '<div class="wpelement-post-card">';
if (has_post_thumbnail()) {
echo '<div class="wpelement-thumb">' . get_the_post_thumbnail(null, 'thumbnail') . '</div>';
}
echo '<h3><a href="' . get_permalink() . '">' . get_the_title() . '</a></h3>';
echo '<p>' . get_the_excerpt() . '</p>';
echo '</div>';
}
Выводы
Создание динамического фильтра записей на WordPress без плагинов даёт полную свободу в настройке и оптимизации. В статье мы рассмотрели базовый пример с фильтрацией по категориям и ценам, AJAX-обновлением и безопасной обработкой данных.
Если хотите расширить функционал, можно интегрировать фильтр с плагинами типа Clearfy Pro для оптимизации или оформить результаты с помощью темы Reboot.