Как сделать пагинацию для постов в логических категориях WordPress

В WordPress часто возникает задача вывести посты, сгруппированные не только по одной категории, но по логическим связям между категориями. Например, показать посты, которые принадлежат одновременно к двум и более категориям, или исключить определённые категории из выборки с пагинацией. Стандартные способы пагинации при этом не всегда работают корректно, особенно при сложных запросах. В этой статье мы разберём, как реализовать пагинацию для постов в логических категориях с помощью WP_Query, а также рассмотрим примеры решения с использованием плагинов и кода.

Почему стандартная пагинация не подходит для логических категорий

WordPress по умолчанию позволяет использовать пагинацию для обычных категорий через архивы или WP_Query с параметром 'cat'. Но если нужно вывести посты, которые удовлетворяют сложным условиям — например, принадлежат к категории А и категории B, или принадлежат к категории А, но не принадлежат к категории B, — стандартная пагинация часто ломается. Это связано с тем, что параметры WP_Query для таксономий не всегда позволяют корректно формировать условия И/ИЛИ/НЕ, а также с особенностями подсчёта общего количества страниц.

В результате пагинация может показывать некорректное число страниц, вести на несуществующие страницы или повторять одни и те же записи.

Для решения этой задачи нам понадобится писать свой запрос с точным условием и вручную рассчитывать параметры пагинации.

Использование WP_Query для пагинации по логическим категориям

Начнём с разбора параметров WP_Query, которые позволяют составлять логические условия по таксономиям. Для этого используется параметр tax_query. Внутри него можно задавать массивы условий с операторами IN, NOT IN, AND и логическими отношениями relation.

Пример запроса, который выведет посты, относящиеся одновременно к категориям с ID 3 и 7 (логическое И):

function wppagenavi_get_posts_logical_categories($paged = 1, $posts_per_page = 10) {
    $args = [
        'post_type' => 'post',
        'posts_per_page' => $posts_per_page,
        'paged' => $paged,
        'tax_query' => [
            'relation' => 'AND',
            [
                'taxonomy' => 'category',
                'field' => 'term_id',
                'terms' => 3,
                'operator' => 'IN',
            ],
            [
                'taxonomy' => 'category',
                'field' => 'term_id',
                'terms' => 7,
                'operator' => 'IN',
            ],
        ],
    ];

    return new WP_Query($args);
}

В этом примере мы используем relation => 'AND' для того, чтобы получить посты, принадлежащие обеим категориям сразу.

Далее нужно вывести пагинацию. Здесь важно корректно посчитать общее число страниц, учитывая сложный запрос. WP_Query сам это делает, но могут быть нюансы с подсчётом при сложных tax_query.

Пример вывода пагинации для логических категорий

После получения объекта WP_Query с нужными постами вы можете вывести посты и пагинацию следующим образом:

$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$query = wppagenavi_get_posts_logical_categories($paged, 5);

if ($query->have_posts()) {
    while ($query->have_posts()) {
        $query->the_post();
        echo '<h2>' . get_the_title() . '</h2>';
        echo get_the_excerpt();
    }

    // Пагинация
    $big = 999999999; // уникальное число для замены
    echo paginate_links([
        'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
        'format' => '?paged=%#%',
        'current' => max(1, $paged),
        'total' => $query->max_num_pages,
        'prev_text' => '« Назад',
        'next_text' => 'Вперед »',
    ]);
} else {
    echo '<p>Посты не найдены.</p>';
}
wp_reset_postdata();

Обратите внимание, что paginate_links корректно работает, если передать правильное количество страниц из объекта WP_Query.

Исключение категорий из пагинации: пример с логикой «НЕ»

Если нужно вывести посты, которые принадлежат к категории 3, но не принадлежат к категории 7, то можно использовать оператор NOT IN в tax_query:

$args = [
    'post_type' => 'post',
    'posts_per_page' => 10,
    'paged' => get_query_var('paged') ?: 1,
    'tax_query' => [
        [
            'taxonomy' => 'category',
            'field' => 'term_id',
            'terms' => 3,
            'operator' => 'IN',
        ],
        [
            'taxonomy' => 'category',
            'field' => 'term_id',
            'terms' => 7,
            'operator' => 'NOT IN',
        ],
    ],
];

$query = new WP_Query($args);

Такой запрос позволяет гибко формировать выборку и одновременно использовать пагинацию.

Решение типичных проблем пагинации при сложных запросах

При сложных tax_query иногда возникают следующие проблемы:

  • Пагинация показывает неправильное число страниц. Это связано с тем, что WP_Query считает общее количество через отдельный запрос, который может игнорировать часть условий.
  • Переходы по страницам ведут на пустые страницы. Такое бывает, если параметры запроса не учитываются в ссылках пагинации.
  • Дублирование постов на разных страницах. Обычно происходит из-за некорректно переданного параметра paged или фильтрации.

Чтобы решить эти проблемы, рекомендуем:

  • Всегда использовать параметр paged из get_query_var('paged').
  • Генерировать ссылки пагинации через функцию paginate_links с корректным параметром base.
  • Использовать правильную структуру tax_query с параметром relation.
  • Если пагинация всё равно даёт сбои, можно добавить фильтр found_posts, чтобы вручную скорректировать общее число постов.

Пример фильтра для корректировки подсчёта постов

Если вы замечаете, что общее количество постов в пагинации неверно, можно переопределить его так:

add_filter('found_posts', 'wppagenavi_correct_found_posts', 10, 2);
function wppagenavi_correct_found_posts($found_posts, $query) {
    // Проверяем, что это наш сложный запрос
    if ($query->is_main_query() && !is_admin() && isset($query->query_vars['tax_query'])) {
        global $wpdb;

        $tax_query = new WP_Tax_Query($query->query_vars['tax_query']);
        $tax_sql = $tax_query->get_sql($wpdb->posts, 'ID', 'term_taxonomy_id');

        // Собираем SQL для подсчёта
        $count_sql = "SELECT COUNT(DISTINCT {$wpdb->posts}.ID) FROM {$wpdb->posts} ";
        $count_sql .= $tax_sql['join'];
        $count_sql .= ' WHERE 1=1 ' . $tax_sql['where'];

        $count = $wpdb->get_var($count_sql);
        return $count ?: $found_posts;
    }

    return $found_posts;
}

Этот код выполняет точный подсчёт количества постов для сложного tax_query и возвращает корректное число для пагинации.

Плагины, которые помогают с пагинацией и логическими категориями

Для упрощения задач с пагинацией при сложных условиях можно использовать плагины:

  • WP-PageNavi — расширяет стандартную пагинацию WordPress удобными стилями и настройками. Хорошо интегрируется с кастомными WP_Query.
  • Clearfy Pro — оптимизационный плагин, который улучшает производительность запросов и пагинации, в том числе с таксономиями. Подробнее: https://wpshop.ru/plugins/clearfy-pro/
  • Expert Review — помогает создавать сложные запросы и выводить посты с пагинацией, удобно для кастомных условий. Подробнее: https://wpshop.ru/plugins/expert-review/

Использование этих плагинов позволяет уменьшить количество кода и упростить поддержку сложной пагинации.

Итоговые рекомендации по созданию пагинации для постов в логических категориях

Подводя итог, можно выделить основные моменты:

  1. Используйте tax_query с правильным relation и операторами IN, NOT IN, AND для создания логики категорий.
  2. Передавайте параметр paged в WP_Query, чтобы пагинация работала корректно.
  3. Для вывода пагинации используйте функцию paginate_links с корректными параметрами.
  4. Если возникают проблемы с подсчётом общего количества постов, применяйте фильтр found_posts с ручным подсчётом.
  5. Рассмотрите возможность использования плагинов, например, WP-PageNavi или Clearfy Pro, для упрощения задачи.
  6. Тестируйте пагинацию на разных страницах и с разными условиями, чтобы исключить дубли и пустые страницы.

Такой подход позволит создавать сложные выборки постов с логическими связями категорий и корректной пагинацией без сбоев и ошибок.

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как сделать пагинацию для кастомных статусов записей в WordPress
01.03.2026
Как сделать пагинацию для таблиц в WordPress с помощью плагинов и кода
18.12.2025
Как сделать пагинацию для комплексных запросов с meta-записями и таксономиями в WordPress
08.03.2026
Как исправить неработающую пагинацию при использовании WP_Query в WordPress
24.04.2026
Как сделать пагинацию для постов в логических категориях WordPress
07.04.2026
×

Создай идеальный сайт – теперь на 15% дешевле!

Подобрать тему →