Пагинация — одна из ключевых функций для удобного просмотра контента на сайте WordPress. Но если вы работаете с комплексными WP_Query, где задействованы несколько параметров, фильтров, мета-запросов и таксономий, стандартные методы пагинации часто не подходят или работают некорректно. В этой статье разберём, как правильно реализовать пагинацию для сложных запросов в WordPress, чтобы она была корректной, эффективной и SEO-дружественной.
Почему стандартная пагинация не работает для комплексных запросов
Когда вы используете WP_Query с несколькими параметрами — например, фильтрация по мета-полям, нескольким таксономиям и произвольным условиям — стандартные функции пагинации WordPress, такие как paginate_links() или previous_posts_link(), могут не учитывать все ваши параметры. В итоге пагинация либо ломается, либо возвращает неправильные страницы.
Это происходит потому, что пагинация работает на основе глобальной переменной $wp_query, а при создании кастомных запросов нужно вручную передавать правильные параметры и синхронизировать пагинацию с текущим запросом.
Для решения этой проблемы необходимо:
- Правильно настроить параметры пагинации, исходя из вашего кастомного WP_Query;
- Учитывать параметры URL, чтобы пагинация корректно передавала фильтры;
- Оптимизировать запросы и минимизировать нагрузку на БД.
Настройка пагинации для комплексного WP_Query: пошаговое руководство
Рассмотрим пример, где нам нужно вывести посты с определённой таксономией, фильтром по мета-полю и сортировкой, а также использовать пагинацию.
Шаг 1. Формируем WP_Query с нужными параметрами
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'post',
'posts_per_page' => 5,
'paged' => $paged,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'novosti',
),
),
'meta_query' => array(
array(
'key' => 'wppagenavi_custom_field',
'value' => 'yes',
'compare' => '=',
),
),
'orderby' => 'meta_value',
'meta_key' => 'wppagenavi_custom_field',
'order' => 'DESC',
);
$custom_query = new WP_Query($args);
Здесь мы берём посты из категории «novosti» с дополнительным фильтром по произвольному полю.
Шаг 2. Выводим посты
Выводим контент в стандартном цикле, используя $custom_query:
if ($custom_query->have_posts()) :
while ($custom_query->have_posts()) : $custom_query->the_post();
the_title('<h2>', '</h2>');
the_excerpt();
endwhile;
endif;
wp_reset_postdata();
Шаг 3. Генерируем ссылки пагинации
Для пагинации используем функцию paginate_links(), но с параметрами, соответствующими нашему запросу:
$big = 999999999; // число для замены
$pagination = paginate_links(array(
'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
'format' => '?paged=%#%',
'current' => max(1, $paged),
'total' => $custom_query->max_num_pages,
'prev_text' => '< Назад',
'next_text' => 'Вперёд >',
));
echo '<nav class="wppagenavi-pagination">' . $pagination . '</nav>';
Важно: если у вас есть дополнительные параметры фильтрации через GET или POST, нужно их передавать в ссылки пагинации, чтобы при переходе фильтры сохранялись.
Передача параметров фильтров в URL пагинации
Если вы используете фильтры, которые меняют содержимое запроса, нужно, чтобы пагинация учитывала эти параметры. Например, если у вас фильтр по дате или тегу, и они передаются в адресной строке, то ссылки пагинации должны содержать эти параметры.
Для этого можно динамически формировать базу пагинации, добавляя параметры с помощью add_query_arg().
$query_args = array();
if (!empty($_GET['filter_date'])) {
$query_args['filter_date'] = sanitize_text_field($_GET['filter_date']);
}
if (!empty($_GET['filter_tag'])) {
$query_args['filter_tag'] = sanitize_text_field($_GET['filter_tag']);
}
$base = add_query_arg($query_args, get_pagenum_link($big));
$base = str_replace($big, '%#%', $base);
$pagination = paginate_links(array(
'base' => $base,
'format' => '?paged=%#%',
'current' => max(1, $paged),
'total' => $custom_query->max_num_pages,
));
Так вы сохраняете контекст фильтров при переходах между страницами.
Оптимизация запросов и кеширование
Комплексные запросы с множеством условий могут сильно нагружать базу данных. Чтобы избежать тормозов, рекомендуется:
- Использовать
transient APIдля кеширования результатов запросов; - Минимизировать количество мета-запросов и таксономий;
- Оптимизировать индексы базы данных и использовать специализированные плагины, например, Clearfy Pro для оптимизации базы и кода.
Пример использования transient для кеширования WP_Query
function wppagenavi_get_cached_query($args) {
$cache_key = 'wppagenavi_query_' . md5(serialize($args)) . '_page_' . (get_query_var('paged') ?: 1);
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
$query = new WP_Query($args);
set_transient($cache_key, $query, 12 * HOUR_IN_SECONDS);
return $query;
}
// Использование:
$args['paged'] = (get_query_var('paged')) ? get_query_var('paged') : 1;
$custom_query = wppagenavi_get_cached_query($args);
Важные советы по SEO пагинации для комплексных запросов
Чтобы не потерять позиции в поисковиках и избежать дублей, используйте:
- Тег
rel="prev"иrel="next"в заголовках страниц пагинации; - Канонические ссылки с атрибутом
rel="canonical"на первую страницу пагинации; - Отдавайте предпочтение ЧПУ в ссылках пагинации, чтобы URL был читабельным и отражал текущие фильтры;
- Проверяйте, чтобы пагинация не мешала индексации полезного контента.
Использование плагина ABC Pagination для комплексных запросов
Если вы хотите упростить создание пагинации для сложных запросов, посмотрите плагин ABC Pagination. Он поддерживает работу с кастомными WP_Query, учитывает параметры URL и позволяет гибко настраивать отображение навигации.
Пример использования с ABC Pagination:
if ($custom_query->have_posts()) :
while ($custom_query->have_posts()) : $custom_query->the_post();
the_title('<h2>', '</h2>');
endwhile;
echo abc_pagination(array('query' => $custom_query));
endif;
wp_reset_postdata();
Итоги
Пагинация для комплексных запросов в WordPress требует тщательной настройки WP_Query, правильной обработки параметров URL и оптимизации запросов. Следуя описанным шагам, вы сможете сделать работоспособную и удобную навигацию по сложным наборам данных, при этом сохранив SEO-эффективность. Используйте кеширование и специальные плагины для повышения производительности и удобства разработки.