В этой статье разберём, как создать динамический фильтрованный список записей WordPress, который обновляется без перезагрузки страницы, используя WP_Query и AJAX. Эта задача часто возникает, когда нужно предоставить пользователям удобный способ быстрого поиска и сортировки контента на сайте.
Что такое фильтрованный список записей и зачем он нужен
Фильтрованный список позволяет посетителю выбрать параметры (категории, метки, пользовательские поля и т.д.) и увидеть соответствующие записи без перезагрузки страницы. Это улучшает UX, ускоряет работу сайта и экономит трафик.
Для реализации такого функционала потребуется:
- Создать интерфейс фильтров на фронтенде;
- Обработать запросы AJAX;
- Сформировать WP_Query с нужными параметрами;
- Вернуть и отобразить результаты динамически.
Подготовка интерфейса фильтров: пример с категориями и метками
Начнём с простого интерфейса, где можно выбрать категории и метки для фильтрации:
<form id="wpdigest-filter-form">
<select name="category" id="wpdigest-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="tag" id="wpdigest-tag">
<option value="">Все метки</option>
<?php
$tags = get_tags();
foreach ($tags as $tag) {
echo '<option value="' . esc_attr($tag->slug) . '">' . esc_html($tag->name) . '</option>';
}
?>
</select>
<button type="submit">Фильтровать</button>
</form>
<div id="wpdigest-results"></div>
Этот код создаёт две выпадающие списки и кнопку для запуска фильтрации. Результаты будут отображаться в контейнере с id wpdigest-results.
Обработка AJAX-запроса на стороне WordPress
Теперь создадим обработчик AJAX, который будет принимать параметры фильтра и возвращать отфильтрованные записи.
Добавим в functions.php или в файл плагина следующий код:
add_action('wp_enqueue_scripts', 'wpdigest_enqueue_scripts');
function wpdigest_enqueue_scripts() {
wp_enqueue_script('wpdigest-filter', get_template_directory_uri() . '/js/wpdigest-filter.js', ['jquery'], null, true);
wp_localize_script('wpdigest-filter', 'wpdigest_ajax', [
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wpdigest_nonce')
]);
}
add_action('wp_ajax_wpdigest_filter_posts', 'wpdigest_filter_posts_callback');
add_action('wp_ajax_nopriv_wpdigest_filter_posts', 'wpdigest_filter_posts_callback');
function wpdigest_filter_posts_callback() {
check_ajax_referer('wpdigest_nonce', 'nonce');
$category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
$tag = isset($_POST['tag']) ? sanitize_text_field($_POST['tag']) : '';
$tax_query = [];
if ($category) {
$tax_query[] = [
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $category,
];
}
if ($tag) {
$tax_query[] = [
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => $tag,
];
}
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'tax_query' => $tax_query ? $tax_query : '',
];
$query = new WP_Query($args);
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();
$content = ob_get_clean();
wp_send_json_success($content);
} else {
wp_send_json_error('Записи не найдены');
}
wp_die();
}
Этот код регистрирует AJAX-обработчик, который принимает выбранные категории и метки, формирует WP_Query с tax_query и возвращает список записей в формате JSON.
JavaScript для отправки AJAX-запроса и обновления результатов
Создайте файл wpdigest-filter.js в папке /js/ вашей темы с таким содержимым:
jQuery(document).ready(function($) {
$('#wpdigest-filter-form').on('submit', function(e) {
e.preventDefault();
var category = $('#wpdigest-category').val();
var tag = $('#wpdigest-tag').val();
$.ajax({
url: wpdigest_ajax.ajax_url,
method: 'POST',
data: {
action: 'wpdigest_filter_posts',
nonce: wpdigest_ajax.nonce,
category: category,
tag: tag
},
beforeSend: function() {
$('#wpdigest-results').html('<p>Загрузка...</p>');
},
success: function(response) {
if(response.success) {
$('#wpdigest-results').html(response.data);
} else {
$('#wpdigest-results').html('<p>' + response.data + '</p>');
}
},
error: function() {
$('#wpdigest-results').html('<p>Ошибка при загрузке данных</p>');
}
});
});
});
Этот скрипт перехватывает отправку формы, отправляет AJAX-запрос с выбранными значениями, а затем обновляет блок с результатами.
Дополнительные улучшения и советы
Добавление пагинации
Чтобы реализовать пагинацию, добавьте параметр paged в WP_Query и передавайте текущую страницу через AJAX. Для управления пагинацией можно использовать HTML-кнопки или бесконечный скролл.
Фильтрация по пользовательским полям (meta_query)
Если нужно фильтровать записи по произвольным полям, добавьте в запрос параметр meta_query. Например, чтобы отфильтровать товары по цене.
Использование плагина Clearfy Pro для оптимизации
Плагин Clearfy Pro поможет оптимизировать работу сайта и уменьшить нагрузку при выполнении сложных WP_Query с фильтрами. Особенно полезно при большом количестве записей.
Итог
Создание динамического фильтрованного списка записей на WordPress с помощью WP_Query и AJAX — мощный инструмент, который улучшит удобство вашего сайта. Такой подход помогает пользователям быстро находить нужный контент без перезагрузки страницы. В статье приведён подробный пример, который вы можете адаптировать под свои нужды.