В этой статье мы рассмотрим, как создать в WordPress реактивный (динамический) фильтрованный вывод постов с использованием AJAX. Такой подход позволяет пользователям быстро и удобно фильтровать записи на сайте без перезагрузки страницы. Это улучшает пользовательский опыт и повышает скорость работы сайта.
Почему стоит использовать AJAX для фильтрации постов в WordPress
Стандартная фильтрация постов в WordPress часто требует перезагрузки страницы — это не всегда удобно, особенно на современных сайтах с большим числом записей. AJAX позволяет отправлять запросы к серверу в фоновом режиме и получать отфильтрованные данные без перезагрузки, что значительно повышает интерактивность.
Кроме того, AJAX-фильтр позволяет реализовать сложные и многоуровневые фильтры (по таксономиям, метаполям, дате и др.) с мгновенным откликом, что актуально для блогов, каталогов, интернет-магазинов и других проектов на WordPress.
Общая структура решения
Наш пример будет включать:
- HTML-разметку с формой фильтрации и контейнером для вывода постов;
- JavaScript-код для отправки AJAX-запросов и обновления контента на странице;
- PHP-функцию, которая будет обрабатывать AJAX-запрос, получать параметры фильтра и возвращать отфильтрованные посты.
Для удобства и безопасности мы используем wp_localize_script для передачи адреса AJAX и nonce.
Пример реализации: фильтрация постов по категории и метаполю
1. Разметка HTML с формой фильтрации
Добавьте в нужном шаблоне WordPress следующий блок:
<form id="wpset-filter-form">
<label>Категория:</label>
<select name="category">
<option value="">Все</option>
<?php
$categories = get_categories();
foreach ($categories as $category) {
echo '<option value="' . esc_attr($category->term_id) . '">' . esc_html($category->name) . '</option>';
}
?>
</select>
<label>Цена (метаполе price):</label>
<input type="number" name="min_price" placeholder="Мин" />
<input type="number" name="max_price" placeholder="Макс" />
<button type="submit">Фильтровать</button>
</form>
<div id="wpset-posts-container">
<!-- Здесь будет вывод постов -->
</div>
2. JavaScript для отправки AJAX-запроса
Добавьте следующий скрипт в файл темы или в отдельный JS-файл и подключите его. В примере используется jQuery (часто включён в WordPress):
jQuery(document).ready(function($) {
$('#wpset-filter-form').on('submit', function(e) {
e.preventDefault();
var data = {
action: 'wpset_filter_posts',
nonce: wpset_ajax.nonce,
category: $(this).find('select[name="category"]').val(),
min_price: $(this).find('input[name="min_price"]').val(),
max_price: $(this).find('input[name="max_price"]').val(),
};
$.post(wpset_ajax.ajax_url, data, function(response) {
if(response.success) {
$('#wpset-posts-container').html(response.data);
} else {
$('#wpset-posts-container').html('<p>Ошибка загрузки постов</p>');
}
});
});
});
3. PHP: регистрация скрипта и локализация данных
function wpset_enqueue_scripts() {
wp_enqueue_script('wpset-filter', get_template_directory_uri() . '/js/wpset-filter.js', ['jquery'], null, true);
wp_localize_script('wpset-filter', 'wpset_ajax', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpset_filter_nonce'),
]);
}
add_action('wp_enqueue_scripts', 'wpset_enqueue_scripts');
4. PHP: обработчик AJAX-запроса
function wpset_ajax_filter_posts() {
check_ajax_referer('wpset_filter_nonce', 'nonce');
$category = isset($_POST['category']) ? intval($_POST['category']) : 0;
$min_price = isset($_POST['min_price']) ? floatval($_POST['min_price']) : 0;
$max_price = isset($_POST['max_price']) ? floatval($_POST['max_price']) : 0;
$meta_query = [];
if ($min_price > 0 || $max_price > 0) {
$price_clause = ['key' => 'price', 'type' => 'NUMERIC'];
if ($min_price > 0) {
$price_clause['value'][] = $min_price;
$price_clause['compare'] = '>=';
}
if ($max_price > 0) {
$price_clause['value'][] = $max_price;
$price_clause['compare'] = isset($price_clause['compare']) ? 'BETWEEN' : '<=';
}
if (count($price_clause['value']) > 1) {
$price_clause['value'] = [$min_price, $max_price];
$price_clause['compare'] = 'BETWEEN';
}
$meta_query[] = $price_clause;
}
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
];
if ($category) {
$args['cat'] = $category;
}
if (!empty($meta_query)) {
$args['meta_query'] = $meta_query;
}
$query = new WP_Query($args);
if ($query->have_posts()) {
ob_start();
while ($query->have_posts()) {
$query->the_post();
?>
<article>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<div><?php the_excerpt(); ?></div>
</article>
<?php
}
wp_reset_postdata();
$html = ob_get_clean();
wp_send_json_success($html);
} else {
wp_send_json_success('<p>Посты не найдены.</p>');
}
wp_die();
}
add_action('wp_ajax_wpset_filter_posts', 'wpset_ajax_filter_posts');
add_action('wp_ajax_nopriv_wpset_filter_posts', 'wpset_ajax_filter_posts');
Советы по улучшению и расширению фильтра
Вы можете добавить дополнительные поля фильтрации, например, по дате публикации, автору или произвольным таксономиям. Для этого расширьте HTML форму и добавьте соответствующие параметры в обработчик PHP.
Также стоит позаботиться о валидации и безопасности данных, а для больших сайтов — добавить кэширование результатов для снижения нагрузки на сервер.
Если нужна SEO-оптимизация, можно реализовать изменение URL при фильтрации с помощью History API и обработку таких URL на сервере.
Использование плагинов для AJAX-фильтрации
Если хотите ускорить разработку или получить более сложный функционал, можно использовать плагины, например:
- Clearfy Pro — содержит расширенные инструменты оптимизации, включая AJAX-фильтры;
- ABC Pagination — для удобной пагинации вместе с AJAX;
- WPRemark — улучшает комментарии и может работать в связке с AJAX.
Эти инструменты помогут упростить создание мощных и удобных сайтов на WordPress.