Динамические фильтры записей — отличный способ улучшить навигацию по сайту и помочь пользователям быстро находить нужный контент. В этой статье мы подробно рассмотрим, как создать собственный динамический фильтр записей в WordPress с помощью PHP и Ajax, без использования готовых плагинов. Кроме того, приведём примеры кода, которые можно адаптировать под свои задачи.
Зачем нужен динамический фильтр записей в WordPress
Стандартные архивы WordPress позволяют выводить записи по категориям, меткам и датам, но не всегда этого достаточно для удобного поиска. Динамический фильтр позволяет пользователям выбирать сразу несколько параметров — например, категорию, метку, автора, дату — и получать результаты без перезагрузки страницы.
Такой фильтр повышает удобство и время нахождения на сайте, что положительно влияет на поведенческие факторы и SEO.
Подготовка: создание формы фильтра
Для начала создадим простую форму, которая позволит выбрать параметры фильтрации. Предположим, что мы хотим фильтровать записи по категории и по дате публикации.
<form id="wpnotes_filter_form">
<select name="category" id="category">
<option value="">Все категории</option>
<?php
$categories = get_categories();
foreach ( $categories as $category ) {
echo '<option value="' . esc_attr($category->slug) . '">' . esc_html($category->name) . '</option>';
}
?>
</select>
<select name="year" id="year">
<option value="">Все годы</option>
<?php
global $wpdb;
$years = $wpdb->get_col("SELECT DISTINCT YEAR(post_date) FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC");
foreach ( $years as $year ) {
echo '<option value="' . esc_attr($year) . '">' . esc_html($year) . '</option>';
}
?>
</select>
<button type="submit">Фильтровать</button>
</form>
<div id="wpnotes_filter_results"></div>Этот код генерирует форму с двумя выпадающими списками: категории и годы публикации. Результаты фильтра будут выводиться в блоке с id wpnotes_filter_results.
Обработка AJAX-запроса для фильтрации
Чтобы сделать фильтр динамическим и не перезагружать страницу, используем AJAX. Для начала добавим JavaScript, который будет отправлять данные формы и получать результаты.
document.getElementById('wpnotes_filter_form').addEventListener('submit', function(e) {
e.preventDefault();
var category = document.getElementById('category').value;
var year = document.getElementById('year').value;
var data = new FormData();
data.append('action', 'wpnotes_filter_posts');
data.append('category', category);
data.append('year', year);
fetch(wpnotes_ajax_object.ajax_url, {
method: 'POST',
credentials: 'same-origin',
body: data
})
.then(response => response.text())
.then(html => {
document.getElementById('wpnotes_filter_results').innerHTML = html;
})
.catch(error => {
console.error('Ошибка:', error);
});
});Здесь wpnotes_ajax_object.ajax_url — это локализованная переменная, которую нужно определить в PHP через wp_localize_script.
Реализация серверной части фильтра
Теперь создадим функцию, которая будет обрабатывать AJAX-запрос и возвращать отфильтрованные записи.
add_action('wp_ajax_wpnotes_filter_posts', 'wpnotes_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpnotes_filter_posts', 'wpnotes_ajax_filter_posts');
function wpnotes_ajax_filter_posts() {
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$year = isset($_POST['year']) ? intval($_POST['year']) : 0;
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'post_status' => 'publish'
];
if ($category) {
$args['category_name'] = $category;
}
if ($year) {
$args['date_query'] = [
[
'year' => $year
]
];
}
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul>';
while ($query->have_posts()) {
$query->the_post();
echo '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a> (' . get_the_date('d.m.Y') . ')</li>';
}
echo '</ul>';
} else {
echo '<p>Записи не найдены.</p>';
}
wp_reset_postdata();
wp_die();
}Эта функция принимает параметры из AJAX, формирует WP_Query с нужными аргументами и возвращает список найденных постов в виде HTML.
Подключение скриптов и локализация AJAX URL
Чтобы JavaScript работал, нужно подключить скрипт и передать ему URL для AJAX-запросов.
function wpnotes_enqueue_scripts() {
wp_enqueue_script('wpnotes-filter', get_template_directory_uri() . '/js/wpnotes-filter.js', ['jquery'], null, true);
wp_localize_script('wpnotes-filter', 'wpnotes_ajax_object', [
'ajax_url' => admin_url('admin-ajax.php')
]);
}
add_action('wp_enqueue_scripts', 'wpnotes_enqueue_scripts');Замените путь /js/wpnotes-filter.js на актуальный для вашего шаблона или плагина.
Расширение фильтра: добавление пользовательских полей и таксономий
Данный пример можно расширить, добавив фильтрацию по произвольным таксономиям или мета-полям. Например, если у вас есть таксономия «город» или мета-поле «цена», вы можете добавить их в форму и модифицировать запрос WP_Query с параметрами 'tax_query' или 'meta_query'.
Такой гибкий фильтр позволит создавать сложные комбинации и значительно улучшить UX.
Фильтрация по произвольной таксономии
Добавьте в форму выбор таксономии, например, city:
<select name="city" id="city">
<option value="">Все города</option>
<?php
$cities = get_terms(['taxonomy' => 'city', 'hide_empty' => true]);
foreach ($cities as $city) {
echo '<option value="' . esc_attr($city->slug) . '">' . esc_html($city->name) . '</option>';
}
?>
</select>И в PHP-обработчике добавить:
$city = isset($_POST['city']) ? sanitize_text_field($_POST['city']) : '';
if ($city) {
$args['tax_query'][] = [
'taxonomy' => 'city',
'field' => 'slug',
'terms' => $city,
];
}Фильтрация по мета-полю
Если нужно фильтровать по произвольному полю, например, цене, добавьте в форму поле для ввода минимальной и максимальной цены, а в запросе WP_Query используйте meta_query:
$min_price = isset($_POST['min_price']) ? floatval($_POST['min_price']) : 0;
$max_price = isset($_POST['max_price']) ? floatval($_POST['max_price']) : 0;
if ($min_price || $max_price) {
$meta_query = ['key' => 'price', 'type' => 'NUMERIC'];
if ($min_price && $max_price) {
$meta_query['value'] = [$min_price, $max_price];
$meta_query['compare'] = 'BETWEEN';
} elseif ($min_price) {
$meta_query['value'] = $min_price;
$meta_query['compare'] = '>=';
} elseif ($max_price) {
$meta_query['value'] = $max_price;
$meta_query['compare'] = '<=';
}
$args['meta_query'][] = $meta_query;
}Использование плагинов для упрощения задачи
Если хочется избежать ручного кодинга, можно обратить внимание на плагины, которые облегчают создание фильтров:
- ABC Pagination — поддерживает фильтрацию и пагинацию с простым интерфейсом.
- WPRemark — мощный плагин для создания динамических форм и фильтров.
Однако понимание базового подхода с AJAX и WP_Query поможет создавать уникальные решения под любые задачи.
Выводы и рекомендации
Динамический фильтр записей — это мощный инструмент для улучшения интерфейса сайта. Важно писать чистый и безопасный код, использовать проверку данных и оптимизировать запросы к базе. При необходимости можно комбинировать собственные решения с плагинами из WPSHOP.
Такой фильтр легко масштабируется, добавляя новые параметры и улучшая опыт пользователей, что положительно сказывается на посещаемости и конверсии сайта.