Вы выбираете категорию или метку, список записей обновляется, а ссылки на следующие страницы исчезают, ведут на полный архив или сбрасывают фильтр. Обычно причина не в самой пагинации: после фильтрации WordPress должен получить корректный запрос записей, а ссылки — сохранить параметры фильтра и номер страницы.
Сначала определите, как устроен список: это обычный архив WordPress, отдельный запрос в шаблоне или выдача, которую обновляет AJAX-скрипт. Способ исправления зависит от этого различия.
Проверьте, где именно ломается навигация
После применения фильтра посмотрите на адрес страницы. Если фильтр передаётся в параметрах вроде ?category_id=12, проверьте, остаётся ли этот параметр при переходе на следующую страницу. Если URL сохраняет фильтр, но список пустой или повторяет те же записи, проблема может быть в настройке запроса или номера страницы. Если URL вообще не меняется, а содержимое обновляется, скорее всего, фильтрация работает через AJAX — тогда отдельно нужно проверить обработчик обновления и код пагинации.
Проверьте также, появляется ли пагинация без фильтра и сколько записей соответствует выбранным условиям. Если после фильтрации результатов меньше, чем задано записей на странице, второй страницы действительно может не быть. Это не ошибка: например, при лимите в 10 записей и семи совпадениях WordPress покажет один список без переходов.
Наконец, убедитесь, что ссылки выводит именно пагинация списка записей. the_posts_pagination() предназначена для страниц архива, а wp_link_pages() разбивает на части одну длинную запись или страницу. Замена одной функции другой не исправит фильтрацию.
Обычный архив: фильтр должен менять основной запрос
Если фильтруется архив категории, метки или записей, обычно проще изменить основной запрос WordPress, а не создавать рядом второй. Для этого разработчик может использовать хук pre_get_posts, проверяя, что запрос выполняется не в админке и является основным. Условия фильтра добавляют к запросу, а тему оставляют выводить архив и штатную пагинацию.
Убедитесь, что шаблон архива выводит записи из основного цикла и после списка вызывает функцию пагинации, например the_posts_pagination(). Если записи вместо этого получены отдельным WP_Query, пагинация основного запроса не знает о количестве страниц пользовательского списка.
Не добавляйте фильтр без проверки типа архива: иначе он может затронуть главную страницу, другие архивы или запросы в виджетах. Для публичного фильтра, передаваемого через GET, считывайте и проверяйте параметры, а не используйте их как готовые значения запроса. При изменении PHP-кода работайте в дочерней теме или отдельном плагине, предварительно сделав резервную копию; правки родительской темы могут исчезнуть после обновления.
Отдельный WP_Query: передайте пагинации тот же запрос
В каталоге записей, на посадочной странице или в кастомном шаблоне фильтр часто формирует отдельный WP_Query. Здесь нужно настроить его сразу с двумя группами параметров: условиями фильтра и номером страницы. А ссылки строить по свойству max_num_pages именно этого запроса.
Ниже пример для отдельной страницы с GET-параметрами category_id и tag_id. Он подходит как основа для шаблона, в котором список действительно выводится через отдельный запрос; названия параметров и условия фильтра должны соответствовать вашей форме.
<?php
$category_id = isset($_GET['category_id'])
? absint(wp_unslash($_GET['category_id']))
: 0;
$tag_id = isset($_GET['tag_id'])
? absint(wp_unslash($_GET['tag_id']))
: 0;
$paged = max(1, (int) get_query_var('paged'));
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
'paged' => $paged,
);
if ($category_id) {
$args['category__in'] = array($category_id);
}
if ($tag_id) {
$args['tag__in'] = array($tag_id);
}
$filtered_posts = new WP_Query($args);
if ($filtered_posts->have_posts()) {
while ($filtered_posts->have_posts()) {
$filtered_posts->the_post();
// Здесь разместите разметку карточки записи.
}
$filter_args = array();
if ($category_id) {
$filter_args['category_id'] = $category_id;
}
if ($tag_id) {
$filter_args['tag_id'] = $tag_id;
}
$links = paginate_links(array(
'total' => $filtered_posts->max_num_pages,
'current' => $paged,
'add_args' => $filter_args,
));
if ($links) {
echo '<nav class="pagination" aria-label="Страницы записей">'
. $links
. '</nav>';
}
} else {
echo '<p>Записи не найдены.</p>';
}
wp_reset_postdata();
?>
В примере paged передаёт запросу текущую страницу, а add_args добавляет выбранные фильтры к ссылкам пагинации. Если пропустить первое, страницы могут повторять одну и ту же выдачу. Если пропустить второе, при переходе фильтр может сброситься. category__in и tag__in здесь принимают ID; для произвольных типов записей и таксономий нужно подобрать соответствующие параметры запроса.
После цикла вызовите wp_reset_postdata(), чтобы восстановить глобальные данные записи для остального шаблона. Если страница сайта использует особую схему постоянных ссылок или вложенные страницы, формирование номера страницы может потребовать адаптации. Проверьте URL и запрос именно на вашем шаблоне, а не переносите пример без проверки.
Как сохранить фильтр при переходе и не получить пустую страницу
Параметры фильтра должны присутствовать в ссылках на страницы. Для ссылок, созданных вручную, добавьте выбранные значения к URL; при использовании paginate_links() для этого предусмотрен аргумент add_args. Не передавайте туда все значения из $_GET без разбора: среди них могут оказаться номер страницы и посторонние параметры. Сформируйте список только из тех фильтров, которые применяет запрос.
При изменении фильтра номер страницы нужно сбрасывать на первую. Допустим, посетитель находился на странице 5 общего архива, а после выбора категории в ней доступно только две страницы. Если форма или скрипт сохранит старое значение paged, результат окажется пустым, хотя записи в категории есть. Убедитесь, что ссылка или форма нового фильтра не отправляет старый номер страницы.
Учитывайте и тип страницы. Для обычного архива текущую страницу обычно читают из paged. У шаблона статической главной страницы в некоторых конфигурациях может использоваться переменная page. Если сайт устроен именно так, проверьте фактический URL и запрос; не подменяйте переменные вслепую — правильное значение зависит от контекста шаблона.
Если список обновляется через AJAX
При AJAX-фильтрации браузер может не перезагружать страницу: JavaScript отправляет фильтр на сервер, получает разметку записей и вставляет её в страницу. В этом сценарии обычные ссылки могут исчезать потому, что скрипт заменяет только список, а не блок навигации. Или обработчик получает фильтр, но не номер страницы, поэтому каждый переход снова загружает первую.
Проверьте, что обработчик AJAX формирует запрос с текущими условиями фильтра и номером страницы, а ответ содержит и обновлённый список, и пагинацию для результата этого запроса. При смене фильтра номер страницы сбрасывайте на первую; при клике на страницу передавайте выбранные фильтры и новый номер. Если ссылки добавляются после обновления списка, обработчики кликов должны работать и для вновь созданных элементов — обычно для этого используют делегирование событий или повторно привязывают обработчики.
Точный способ зависит от плагина фильтрации или собственного JavaScript. Сначала проверьте параметры запроса в инструментах разработчика браузера и ответ сервера. Если сервер уже возвращает правильные ссылки, а навигация не реагирует, ищите проблему в скрипте темы или фильтра, а не в настройках WordPress.
WP-PageNavi не заменяет правильный запрос
WP-PageNavi меняет представление навигации, но не исправляет неверное число страниц, отсутствие параметра paged в запросе или сброс фильтра в ссылках. При основном цикле достаточно штатной пагинации темы, если она корректно работает с архивом. Если проект уже использует WP-PageNavi, проверьте, что его вызов расположен после нужного цикла.
Для отдельного запроса плагину нужно передать объект этого запроса, например вызовом wp_pagenavi(array('query' => $filtered_posts));. Такая интеграция зависит от версии плагина и шаблона. После установки или изменения вызова отдельно проверьте, что номера страниц относятся к отфильтрованному списку и ссылки сохраняют GET-параметры. Если тема или плагин фильтрации самостоятельно перехватывает переходы, может потребоваться настройка именно их совместной работы.
Проверьте исправление на нескольких фильтрах
Откройте архив без фильтра, затем выберите категорию или метку, у которой заведомо больше одной страницы результатов. Перейдите на следующую страницу и убедитесь, что фильтр остался выбран, URL соответствует второй странице, а записи отличаются от первой. Затем смените фильтр, находясь на второй или более поздней странице: результат должен открыться с первой страницы нового списка.
Если ссылки ведут правильно, но показывают неподходящие записи, проверьте условия и параметры запроса. Если запрос считает страницы правильно, но ссылки теряют фильтр — исправьте их генерацию. Если проблема возникает только при AJAX, исследуйте запрос и ответ обработчика. Такое разделение обычно быстрее находит причину, чем переустановка плагина пагинации или случайная правка стилей.