В WordPress стандартная пагинация отлично работает для простых запросов, но когда вы используете комплексные WP_Query с несколькими параметрами — фильтрами, сортировками и кастомными полями — возникает множество сложностей. Добавление AJAX-пагинации в такие запросы значительно улучшит пользовательский опыт, позволяя загружать новые страницы без перезагрузки.
Почему стандартная пагинация не всегда подходит для комплексных запросов
Стандартная пагинация WordPress строится на глобальной переменной $wp_query и URL-параметре paged. Для сложных запросов, использующих кастомные параметры и фильтры, часто применяется отдельный объект WP_Query. В этом случае пагинация в шаблоне может не работать корректно, так как WordPress не знает, на какую страницу ссылаться, и как правильно считать общее количество страниц.
Кроме того, при использовании нескольких фильтров (например, по таксономиям, метаполям, пользовательским параметрам) нужно учитывать, что пагинация должна сохранять и передавать все эти параметры при переходе между страницами. Иначе пользователь потеряет выбранные фильтры.
Наконец, при обновлении контента через AJAX пагинация должна динамически подгружать новые записи и обновлять URL без перезагрузки страницы. Всё это требует дополнительной логики и правильной интеграции.
Создание комплексного WP_Query с поддержкой пагинации
Рассмотрим пример комплексного запроса, который выбирает посты по нескольким таксономиям и метаполям с сортировкой.
function wppagenavi_get_complex_query() {
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => $paged,
'tax_query' => [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'news',
],
],
'meta_query' => [
[
'key' => 'featured',
'value' => '1',
'compare' => '=',
],
],
'orderby' => 'date',
'order' => 'DESC',
];
return new WP_Query($args);
}
Обратите внимание, что параметр paged передается в запрос, чтобы пагинация работала корректно.
Добавление AJAX пагинации: шаги и пример реализации
Для реализации AJAX пагинации необходимо:
- Создать обработчик AJAX-запроса в PHP, который принимает параметры страницы и фильтры, запускает WP_Query и возвращает HTML.
- Добавить JavaScript, который будет перехватывать клики по ссылкам пагинации, отправлять AJAX-запросы и подставлять полученный HTML в нужный блок.
- Обеспечить правильное обновление URL с помощью History API для удобства навигации и SEO.
PHP: обработчик AJAX запроса
add_action('wp_ajax_wppagenavi_load_posts', 'wppagenavi_ajax_load_posts');
add_action('wp_ajax_nopriv_wppagenavi_load_posts', 'wppagenavi_ajax_load_posts');
function wppagenavi_ajax_load_posts() {
$paged = isset($_POST['page']) ? intval($_POST['page']) : 1;
// Здесь можно получить дополнительные фильтры из $_POST
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => $paged,
// Добавьте сюда фильтры из AJAX-запроса
];
$query = new WP_Query($args);
if($query->have_posts()) {
ob_start();
while($query->have_posts()) {
$query->the_post();
// Выводите разметку поста
?>
<article id="post-<?php the_ID(); ?>">
<h2><?php the_title(); ?></h2>
<div><?php the_excerpt(); ?></div>
</article>
<?php
}
$content = ob_get_clean();
// Формируем пагинацию
$pagination = paginate_links([
'total' => $query->max_num_pages,
'current' => $paged,
'type' => 'array',
]);
wp_send_json_success(['content' => $content, 'pagination' => $pagination]);
} else {
wp_send_json_error('Посты не найдены');
}
wp_die();
}
JavaScript: отправка AJAX запроса и обновление контента
jQuery(document).ready(function($){
function wppagenavi_load_page(page) {
$.ajax({
url: ajaxurl, // В фронтенде замените на wp_localize_script
type: 'POST',
dataType: 'json',
data: {
action: 'wppagenavi_load_posts',
page: page
// сюда добавляйте фильтры
},
success: function(response) {
if(response.success) {
$('#posts-container').html(response.data.content);
$('#pagination-container').html('');
if(response.data.pagination.length) {
var paginationHtml = '';
$.each(response.data.pagination, function(i, link) {
paginationHtml += link;
});
$('#pagination-container').html(paginationHtml);
}
// Обновляем URL
history.pushState(null, null, '?paged=' + page);
} else {
$('#posts-container').html('<p>Посты не найдены</p>');
$('#pagination-container').html('');
}
}
});
}
// Перехват кликов по пагинации
$(document).on('click', '#pagination-container a', function(e){
e.preventDefault();
var page = $(this).text();
if(page === '«' || page === '»') {
page = $(this).attr('href').split('paged=')[1];
}
wppagenavi_load_page(page);
});
});
Поддержка фильтров и пользовательских параметров
В реальных проектах пагинация часто идет вместе с фильтрами по таксономиям, метаполям и другим параметрам. Для этого необходимо в AJAX-запросе передавать все выбранные фильтры, а в PHP обрабатывать их при формировании WP_Query.
Например, добавим фильтр по таксономии 'genre' и метаполю 'rating':
// В JS добавляем параметры
var genre = $('#genre-filter').val();
var rating = $('#rating-filter').val();
data: {
action: 'wppagenavi_load_posts',
page: page,
genre: genre,
rating: rating
}
// В PHP
$tax_query = [];
if(!empty($_POST['genre'])) {
$tax_query[] = [
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => sanitize_text_field($_POST['genre']),
];
}
$meta_query = [];
if(!empty($_POST['rating'])) {
$meta_query[] = [
'key' => 'rating',
'value' => sanitize_text_field($_POST['rating']),
'compare' => '>='
];
}
$args['tax_query'] = $tax_query;
$args['meta_query'] = $meta_query;
Такой подход позволяет гибко формировать запросы и обновлять контент без перезагрузки.
Советы по оптимизации и кешированию
При сложных запросах с фильтрами пагинация может замедляться из-за нагрузки на базу данных. Рекомендуется использовать кеширование результатов, например, через Transients API или плагины кеширования. Также полезно применять индексы к метаполям и таксономиям для ускорения выборки.
Если вы используете плагин WP-PageNavi, его можно интегрировать с AJAX пагинацией для более удобного вывода ссылок. Для этого генерируйте пагинацию через wp_pagenavi() и передавайте её в AJAX-ответ.
Заключение
Создание пагинации для комплексных запросов с AJAX в WordPress требует точной настройки WP_Query, правильной обработки AJAX-запросов и грамотного обновления интерфейса. Такой подход значительно улучшает UX и позволяет реализовать мощные фильтры и сортировки без перезагрузки страницы.
Для удобной реализации можно использовать плагины, например, ABC Pagination от WPShop, который поддерживает AJAX и кастомные параметры.