Диагностика проблемы: почему пагинация не работает на страницах архива
Частая ошибка при кастомизации запросов WordPress — изменение главного запроса (main query) через pre_get_posts без правильной проверки условий. В результате пагинация перестаёт работать: при переходе на следующую страницу отображается тот же набор записей или 404 ошибка.
Чтобы диагностировать, вызвана ли проблема этим фильтром, временно отключите все сторонние фильтры, которые изменяют запрос, и проверьте работу пагинации. Если проблема исчезла, значит, дело в неправильной настройке pre_get_posts.
Пошаговое решение: правильное применение pre_get_posts для пагинации
1. Определите контекст главного запроса
Всегда проверяйте, что вы изменяете именно главный запрос на нужной странице. Для этого используйте условие is_main_query() и дополнительные условные теги, например, is_archive(), is_post_type_archive('custom_post_type') или is_category().
2. Не изменяйте свойства paged вручную
Чтобы пагинация работала, параметр paged должен передаваться из запроса WordPress. Не задавайте его вручную, иначе пагинация сломается.
3. Правильная реализация фильтра
Пример корректного кода для изменения количества записей на странице архива кастомного типа записи:
function custom_modify_archive_query( \WP_Query $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive('product') ) {
$query->set('posts_per_page', 12);
// Не трогаем 'paged'! WordPress сам передаст нужное значение
}
}
add_action('pre_get_posts', 'custom_modify_archive_query');Проверка результата после внедрения
- Перейдите на страницу архива (например,
example.com/product/). - Проверьте, что количество записей на странице равно 12 (как в примере).
- Переключитесь на вторую страницу пагинации (например,
example.com/product/page/2/). - Убедитесь, что отображаются следующие 12 записей, а не те же или 404 ошибка.
Частые ошибки и как их исправить
- Ошибка: Изменение параметра
pagedвручную вpre_get_posts.
Почему: WordPress сам управляет этим параметром для пагинации.
Как исправить: Уберите строки кода, которые делают$query->set('paged', 1)или аналогичные. - Ошибка: Применение фильтра ко всем запросам, включая админку.
Почему: Изменения влияют на wp-admin и могут сломать административные списки.
Как исправить: Добавьте проверку! is_admin()в условие. - Ошибка: Не проверяется, что запрос главный (без
is_main_query()).
Почему: Изменения влияют на все запросы, включая вторичные.
Как исправить: Добавьте проверку$query->is_main_query().
Практические советы по безопасности и производительности
- Избегайте тяжелых условий в
pre_get_posts, чтобы не замедлять загрузку страниц. - Кэшируйте результаты запросов, если количество записей и параметры редко меняются.
- Не изменяйте запросы в хуках, запускаемых после
pre_get_posts, чтобы избежать конфликтов.
Дополнительные примеры кода
Если нужно добавить сортировку по метаполю с сохранением пагинации, используйте:
function custom_sort_archive_query( \WP_Query $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive('product') ) {
$query->set('meta_key', 'price');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'ASC');
$query->set('posts_per_page', 10);
}
}
add_action('pre_get_posts', 'custom_sort_archive_query');Обязательно проверьте, что пагинация работает по описанной выше схеме.
Таблица сравнения вариантов использования пагинации
| Вариант | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
Изменение main query через pre_get_posts | Простой, не требует переопределения шаблонов | Легко ошибиться с проверками, пагинация может сломаться | Для простых изменений параметров вывода на архивах |
| Создание кастомного WP_Query в шаблоне | Полный контроль над запросом | Нужно вручную обрабатывать пагинацию | Для сложных кастомных страниц с нестандартной логикой |