Пагинация кастомных записей с фильтрами с помощью WP-PageNavi

Одной из частых задач в разработке на WordPress является создание удобной пагинации для кастомных типов записей (Custom Post Types, CPT) с дополнительными фильтрами. Плагин WP-PageNavi отлично справляется с задачей кастомной пагинации, однако требует правильной настройки для работы с кастомными запросами и фильтрами. В этой статье подробно разберём, как реализовать такую пагинацию, включая примеры кода и рекомендации по оптимизации.

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

Стандартная пагинация WordPress, основанная на paginate_links() или функциях типа the_posts_pagination(), отлично работает для обычных запросов на посты. Но когда речь идёт о кастомных типах записей и фильтрации по мета-данным или таксономиям, возникает необходимость создавать свои WP_Query с параметрами, а пагинация должна учитывать эти параметры.

Здесь и возникает необходимость использовать WP-PageNavi, который позволяет более гибко контролировать вывод пагинации и интегрироваться с кастомными запросами.

Основные шаги для реализации пагинации кастомных записей с фильтрами

Для начала рассмотрим классический пример: есть кастомный тип записей product и фильтр по мета-полю price_range. Нужно вывести список продуктов с пагинацией и фильтрацией.

Создание кастомного запроса с учётом пагинации

Первым делом нужно сформировать правильный WP_Query, учитывающий текущую страницу и параметры фильтра.

function wppagenavi_get_filtered_products() {
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $price_range = isset($_GET['price_range']) ? sanitize_text_field($_GET['price_range']) : '';

    $meta_query = [];
    if ($price_range) {
        if ($price_range === 'low') {
            $meta_query[] = [
                'key' => 'price',
                'value' => [0, 100],
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC'
            ];
        } elseif ($price_range === 'medium') {
            $meta_query[] = [
                'key' => 'price',
                'value' => [101, 500],
                'compare' => 'BETWEEN',
                'type' => 'NUMERIC'
            ];
        } elseif ($price_range === 'high') {
            $meta_query[] = [
                'key' => 'price',
                'value' => 501,
                'compare' => '>=',
                'type' => 'NUMERIC'
            ];
        }
    }

    $args = [
        'post_type' => 'product',
        'posts_per_page' => 10,
        'paged' => $paged,
        'meta_query' => $meta_query
    ];

    return new WP_Query($args);
}

Здесь мы берём параметр paged из запроса и собираем мета-запрос для фильтрации по цене.

Вывод результатов и пагинации с WP-PageNavi

Далее нужно вывести записи и использовать WP-PageNavi для отображения пагинации.

$query = wppagenavi_get_filtered_products();

if ($query->have_posts()) :
    echo '<div class="products-list">';
    while ($query->have_posts()) : $query->the_post();
        echo '<h2>' . get_the_title() . '</h2>';
        echo '<div>Цена: ' . get_post_meta(get_the_ID(), 'price', true) . '</div>';
    endwhile;
    echo '</div>';

    // Пагинация
    echo wppagenavi();

    wp_reset_postdata();
else :
    echo '<p>Продукты не найдены.</p>';
endif;

Важно, чтобы функция wppagenavi() работала с текущим WP_Query. По умолчанию WP-PageNavi берёт глобальный $wp_query, поэтому если используете кастомный запрос, нужно временно заменить глобальный объект.

Подключение WP-PageNavi к кастомному запросу

Чтобы пагинация корректно работала, используем следующий приём:

global $wp_query;
$tmp_query = $wp_query;
$wp_query = $query;

wppagenavi();

$wp_query = $tmp_query;

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

Добавление параметров фильтра в ссылки пагинации

Очень важный момент — при фильтрации параметры $_GET должны сохраняться в URL пагинации, иначе при переходе по страницам фильтр пропадёт.

WP-PageNavi не поддерживает это из коробки, поэтому нам нужно добавить фильтр, который будет дополнять ссылки нужными параметрами.

add_filter('wp_pagenavi', 'wppagenavi_add_query_args', 10, 2);
function wppagenavi_add_query_args($html, $args) {
    if (!empty($_GET)) {
        $query_args = $_GET;
        // Исключаем параметр paged, он подставляется отдельно
        unset($query_args['paged']);

        foreach ($query_args as $key => $value) {
            $html = preg_replace_callback('/href="([^"]+)"/', function($matches) use ($key, $value) {
                $url = $matches[1];
                $url = add_query_arg($key, $value, $url);
                return 'href="' . esc_url($url) . '"';
            }, $html);
        }
    }
    return $html;
}

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

Оптимизация и кеширование результатов пагинации

При использовании кастомных запросов с фильтрами и пагинацией важно учитывать нагрузку на базу данных. Особенно если фильтров много и данных много.

Рекомендуется использовать кеширование результатов запроса, например, через Transients API или кеширование на уровне сервера (Redis, Memcached), чтобы не запускать однотипные запросы постоянно.

Пример простого кеширования с Transients API:

function wppagenavi_get_filtered_products_cached() {
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $price_range = isset($_GET['price_range']) ? sanitize_text_field($_GET['price_range']) : '';

    $transient_key = 'wppagenavi_products_' . md5($paged . '_' . $price_range);
    $query = get_transient($transient_key);

    if (false === $query) {
        $query = wppagenavi_get_filtered_products();
        set_transient($transient_key, $query, 3600); // кеш на час
    }

    return $query;
}

Замените вызов функции в шаблоне на wppagenavi_get_filtered_products_cached(), чтобы снизить нагрузку.

Поддержка AJAX пагинации для кастомных записей с фильтрами

Для улучшения UX можно реализовать AJAX пагинацию, чтобы при смене страницы или фильтра не перезагружать всю страницу.

Для этого понадобится JavaScript-код, который будет отправлять AJAX-запрос с параметрами фильтра и страницы, и PHP-обработчик, который вернёт HTML списка и пагинации.

Пример простого AJAX обработчика:

add_action('wp_ajax_wppagenavi_filter', 'wppagenavi_ajax_filter_handler');
add_action('wp_ajax_nopriv_wppagenavi_filter', 'wppagenavi_ajax_filter_handler');

function wppagenavi_ajax_filter_handler() {
    $paged = isset($_POST['paged']) ? intval($_POST['paged']) : 1;
    $price_range = isset($_POST['price_range']) ? sanitize_text_field($_POST['price_range']) : '';

    // Формируем запрос
    $_GET['paged'] = $paged;
    $_GET['price_range'] = $price_range;
    $query = wppagenavi_get_filtered_products();

    ob_start();
    if ($query->have_posts()) {
        while ($query->have_posts()) : $query->the_post();
            echo '<h2>' . get_the_title() . '</h2>';
        endwhile;
        
        global $wp_query;
        $tmp_query = $wp_query;
        $wp_query = $query;
        wppagenavi();
        $wp_query = $tmp_query;
    } else {
        echo '<p>Продукты не найдены.</p>';
    }
    wp_reset_postdata();

    $response = ob_get_clean();

    wp_send_json_success($response);
}

Клиентский JS должен отправлять AJAX-запрос на admin-ajax.php с параметрами фильтра и страницы, и обновлять содержимое списка и пагинации.

Выводы и рекомендации

  • Используйте WP-PageNavi с кастомными запросами, временно заменяя глобальный $wp_query.
  • Обязательно сохраняйте параметры фильтров в ссылках пагинации с помощью фильтра wp_pagenavi.
  • Реализуйте кеширование запросов для снижения нагрузки на базу.
  • Для лучшего UX добавьте AJAX пагинацию с обновлением контента без перезагрузки страницы.
  • Проверяйте и фильтруйте входящие параметры, чтобы избежать ошибок и уязвимостей.

Если хотите расширить функционал, обратите внимание на плагин WP-PageNavi Pro с дополнительными настройками и поддержкой AJAX.

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

⭐⭐⭐⭐⭐
Как добавить AJAX пагинацию в WP-PageNavi с поддержкой кеширования
04.01.2026
Как сделать пагинацию для комплексных запросов с meta-записями в WordPress
25.02.2026
Как сделать пагинацию для контента в Page Builder WordPress
16.01.2026
Как исправить несоответствие пагинации при использовании WP_Query в WordPress
21.04.2026
Как добавить пагинацию в WP Admin для кастомных типов записей
28.03.2026
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше