Не работает пагинация в WordPress

Не работает пагинация в WordPress

Решаем один из самых популярных вопросов у разработчиков WordPress: «Почему не работает пагинация?»

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

Существуют страницы записей(постов/страниц/кастомных типов записей(CPT)) или архивные страницы(архивные/терминов страницы и страница поиска).

Пагинация на странице записей

В целом пагинацию можно разбить на 3 небольших этапа:

  • Делаем правильную выборку при помощи WP_Query;
  • Выводим пагинацию;
  • Выводим 404, когда данное надо

WP_Query для пагинации

$current = absint(max(1,get_query_var( 'paged')? get_query_var( 'paged'): get_query_var( 'page')));$posts_per_page = 3;$query = new WP_Query(['post_type' => 'post','posts_per_page' => $posts_per_page,'paged' => $current,]);

Необходимо обратить внимание на настройка paged в WP_Query, он говорит о том, какую страницу данного запроса вывести. При помощи возможностей get_query_var() мы получаем номер текущей страницы …/page/{# страницы}. В зависимости от типа страницы мы должны использовать get_query_var( 'paged') или get_query_var( 'page'). Я решил написать универсальный вариант, который подойдет к любому типу страниц.

Отображение пагинации

Для вывода пагинации используем возможность paginate_links:

echo wp_kses_post(paginate_links(['total' => $query->max_num_pages,'current' => $current,]));

В возможность paginate_links необходимо передать два параметры: total — число страниц и current — текущую страницу.

Так же можно использовать the_posts_pagination, но важно помнить, что данная функцию работает только с глобальным wp_query и ее вызов выглядит примерно так:

global $wp_query;$restore_wp_query = $wp_query;$wp_query    = $query;the_posts_pagination();$wp_query = $restore_wp_query;

Отображение 404 в случае, когда данных нет

if( $query->have_posts()) {...} else {global $wp_query;$wp_query->set_404();status_header( 404);nocache_headers();require get_404_template();}

Устанавливаем 404 ответ в глобальный WP_Query. Ставим 404 статус ответа для сервера. nocache_headers — дает функция сбросить кеш для заголовков ответа во всех браузерах. И подключаем 404 страницу при помощи require get_404_template().

Важно, чтобы до вывода данных ф-ций ничего не выводилось на странице!

Результат

$current = absint(max(1,get_query_var( 'paged')? get_query_var( 'paged'): get_query_var( 'page')));$posts_per_page = 3;$query          = new WP_Query(['post_type'      => 'post','posts_per_page' => $posts_per_page,'paged'          => $current,]);if( $query->have_posts()) {?><h1>Текущая страница <?php echo absint( $current);?></h1><?phpwhile( $query->have_posts() ) {$query->the_post();the_title();echo '<br>';}wp_reset_postdata();echo wp_kses_post(paginate_links(['total'   => $query->max_num_pages,'current' => $current,]));} else {global $wp_query;$wp_query->set_404();status_header( 404 );nocache_headers();require get_404_template();}

Пагинация на архивный страницах

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

Пример страницы

if ( have_posts() ) {while( have_posts() ) {the_post();the_title();echo '<br>';}wp_reset_postdata();}

Пагинация

Для архивных страниц можно использовать возможность the_posts_pagination .

if ( have_posts() ) {while( have_posts() ) {the_post();the_title();echo '<br>';}wp_reset_postdata();the_posts_pagination();}

Важно , что данная функцию работает только с глобальным wp_query .

Изменяем результат запроса при помощи pre_get_posts

Добавляем в functions.php :

add_action( 'pre_get_posts', 'customize_search_query' );function customize_search_query( WP_Query $wp_query ) {if ( $wp_query->is_main_query() && ! $wp_query->is_admin() && $wp_query->is_search() ) {$wp_query->set( 'cat', 10 );}}

С данным хуком необходимо быть осторожным. Для начала необходимо проверить, что данный запрос будет основным при помощи способа is_main_query . Так же проверить, что данных запрос вызывается на фронте при помощи is_admin и то, что данный запрос будет поиском is_search . Далее устанавливаем конкретную категорию set( 'cat', 10 );

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *