Диагностика проблемы: почему пагинация не работает при нескольких WP_Query
Часто на странице WordPress может быть несколько независимых запросов WP_Query, например, вывод последних новостей и популярных товаров. Если у всех запросов используется стандартный параметр paged из глобального запроса, они конфликтуют между собой. В результате пагинация работает только для одного из запросов, остальные либо показывают дублирующиеся страницы, либо выдают ошибку 404.
Признаки проблемы:
- При переключении страницы пагинации меняются одновременно все блоки с WP_Query.
- Переход на следующую страницу приводит к 404, хотя в URL указан правильный номер страницы.
- Пагинация работает корректно только у одного блока, остальные игнорируют параметр
paged.
Почему так происходит
WP_Query использует параметр paged для определения текущей страницы. По умолчанию он берётся из запроса URL, например, ?paged=2. Если на странице несколько запросов, все берут значение paged из одного и того же параметра, что некорректно — каждому запросу нужна своя независимая нумерация страниц.
Пошаговое решение: как реализовать независимую пагинацию для нескольких WP_Query
1. Используйте разные параметры пагинации в URL
Для каждого WP_Query нужно использовать отдельный параметр, например, paged_1, paged_2. В URL это будет выглядеть так:
?paged_1=2&paged_2=12. Получайте параметры пагинации для каждого запроса
В PHP коде шаблона извлеките параметры из $_GET и передайте их в WP_Query:
$paged_1 = isset($_GET['paged_1']) ? max(1, intval($_GET['paged_1'])) : 1;
$paged_2 = isset($_GET['paged_2']) ? max(1, intval($_GET['paged_2'])) : 1;
$query1 = new WP_Query(array(
'post_type' => 'post',
'paged' => $paged_1,
'posts_per_page' => 5
));
$query2 = new WP_Query(array(
'post_type' => 'product',
'paged' => $paged_2,
'posts_per_page' => 4
));3. Генерируйте ссылки пагинации с правильными параметрами
Вызов функции paginate_links() или previous_posts_link() нужно модифицировать так, чтобы в URL добавлялся именно нужный параметр пагинации, без изменения других параметров.
Пример генерации пагинации для первого запроса:
echo paginate_links(array(
'base' => add_query_arg('paged_1', '%#%'),
'format' => '',
'current' => $paged_1,
'total' => $query1->max_num_pages
));Для второго запроса замените paged_1 на paged_2 и $paged_1 на $paged_2.
4. Сохраняйте остальные GET-параметры при переходах
Чтобы не сбрасывать другие параметры (например, фильтры или сортировку), используйте функцию add_query_arg() аккуратно, передавая все текущие параметры, кроме изменяемого:
$current_params = $_GET;
$current_params['paged_1'] = '%#%';
unset($current_params['paged_2']); // если нужно
$base = add_query_arg($current_params, get_permalink());Проверка результата после внедрения
- Перейдите на страницу с несколькими блоками WP_Query.
- Щёлкните по пагинации первого блока — в URL должен меняться параметр
paged_1, а содержимое блока — обновляться на соответствующую страницу. - Проверьте пагинацию второго блока — изменяется параметр
paged_2и обновляется только второй блок. - Ошибок 404 при переходах по пагинации быть не должно.
Частые ошибки и как их исправить
- Использование одного параметра
pagedдля всех запросов. Решение: обязательно назначайте уникальные GET-параметры для каждого запроса. - Неправильная генерация ссылок пагинации. Используйте
add_query_arg(), чтобы не терять другие параметры URL. Не формируйте ссылки вручную. - Отсутствие обработки параметров
$_GET. Всегда валидируйте и фильтруйте входящие данные, например, с помощьюintval()иmax(1, ...). - Забыли передать параметр
pagedв WP_Query. Обязательно передавайтеpagedв аргументах запроса WP_Query.
Практические советы для производительности и безопасности
- При большом количестве запросов пагинации на одной странице стоит кэшировать результаты с помощью Transients API или плагинов кеширования.
- Не выводите слишком много записей на страницу — оптимизируйте
posts_per_pageс учётом производительности. - Валидация параметров пагинации предотвращает ошибки и атаки с поддельными URL.
- При использовании AJAX пагинации дополнительно фильтруйте и проверяйте передаваемые параметры.
Таблица сравнения вариантов реализации пагинации для нескольких WP_Query
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
| 1. Отдельные GET-параметры | Простая реализация, независимость запросов, совместимость с SEO | Увеличение длины URL, сложность поддержки при большом числе запросов | paged_1, paged_2 + передача в WP_Query |
| 2. AJAX пагинация с передачей параметров | Быстрая загрузка, без перезагрузки страницы | Сложнее в реализации, требует JS, SEO сложнее | AJAX вызовы с передачей paged в data-атрибутах |
3. Универсальный параметр paged для всех | Простота URL | Работает только с одним запросом, конфликты | paged в WP_Query для одного запроса |