Как сделать числовую пагинацию в WordPress без плагинов

В данной статье я хочу показать вам, как добавить числовую пагинацию в WordPress к вашему блогу без каких-либо плагинов. Числовая пагинация, которую я собираюсь реализовать, используется на данном сайте (если вы перейдете в раздел блога и прокрутите в самый низ, то вы поймете, о чем я веду речь; примечание переводчика – примерно такая же реализация используется и на данном блоге, только через плагин). Я написал этот пост, поскольку я считаю, что людям обычно трудно добавить постраничное разбиение (пагинацию) к существующему сайту. Я регулярно сталкиваюсь с темами на форумах WordPress.org, где пользователи задают похожие вопросы: «Как мне добавить пагинацию к моей странице блога?», «Как мне добавить эти циферки в самом низу страницы, чтобы пользователи могли перемещаться по записям?» или «Как мне разбить мой блог на многочисленные страницы?» Складывается впечатление, что большинство пользователей выбирает для себя именно числовое разбиение на страницы в WordPress вместо навигации с помощью стандартных ссылок «Предыдущая страница» и «Следующая страница», которая в реальности никак не говорит о том, где именно пользователь находится в данный момент.

Базовая пагинация с помощью двух ссылок «Следующая страница» и «Предыдущая страница» достаточно просто реализуется, о чем прекрасно написано в кодексе, однако эта навигация не является самой удобной. Представьте себе, что пользователь пришел на ваш сайт, добрался до 8 страницы с нужной записью и ушел. Затем он вернулся обратно и решил получить тот же пост на 8 странице – для этого ему понадобится пролистать кучу страниц. Представьте себе, насколько это раздражающее действие. Это говорит о плохом юзабилити, и такого подхода желательно избегать, если вы не хотите, чтобы пользователи больше к вам не возвращались.

Базовая настройка: произвольный запрос WP_Query

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

<?php
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1
 
$args = array(
   'posts_per_page' => 6,
   'paged' => $paged
);
 
$custom_query = new WP_Query( $args );
 
while($custom_query->have_posts()) : 
   $custom_query->the_post();	
?>
   <div>
	<ul>
	  <li>
	    <h3><a class="blog-title" href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a></h3>
		<span>Written <i>by:&nbsp;</i> <a class="link" href="<?php bloginfo('url'); ?>/author/<?php the_author(); ?>"> <?php the_author(); ?></a> <i>on</i> <?php the_time('F j, Y'); ?> <a class="link" href="<?php the_permalink(); ?>#comments "><?php comments_number( '', '- 1 comment', '- % comments' ); ?></a></span>
		<div>
		   <ul>
			<div><a href="<?php the_permalink(); ?>"><?php the_post_thumbnail('thumbnail'); ?></a></div>
		   </ul>
		   <ul>
			<li class="work-description"><?php echo the_excerpt(); ?></li>
		   </ul>				
		</div>	
		<div><?php the_tags(); ?>			
	   </li>
	</ul>
   </div> <!-- end blog posts -->	
 
     <?php endwhile; ?>		
   </div>

Примечание: код выше используется для примера. Если вы просто скопируете его и вставите в свой файл, то все стили будут нарушены. При необходимости код можно скорректировать, чтобы он отвечал вашим требованиям. Также обратите внимание на переменную, которую мы используем для хранения нашего запроса, $custom_query, поскольку она будет использоваться, чтобы вывести на экран пагинацию для данного конкретного запроса.

В самом начале нашего запроса мы задаем переменную $paged, которая будет использоваться внутри нашего произвольного запроса. Она нужна для того, чтобы указать WordPress, на какой странице пагинации мы в данный момент находимся. Без этих двух переменных числовая пагинация в WordPress будет неправильно работать.

Стили пагинации

Следующие стили помещаются непосредственно в основной файл .CSS вашей темы. Эти стили определяют способ вывода на экран пагинации вашего сайта.

/* Pagination */
.pagination {
    clear:both;
    position:relative;
    font-size:11px; /* Pagination text size */
    line-height:13px;
    float:right; /* Pagination float direction */
}
 
.pagination span, .pagination a {
    display:block;
    float:left;
    margin: 2px 2px 2px 0;
    padding:6px 9px 5px 9px;
    text-decoration:none;
    width:auto;
    color:#fff; /* Pagination text color */
    background: #555; /* Pagination non-active background color */
    -webkit-transition: background .15s ease-in-out;
    -moz-transition: background .15s ease-in-out;
    -ms-transition: background .15s ease-in-out;
    -o-transition: background .15s ease-in-out;
    transition: background .15s ease-in-out;
}
 
.pagination a:hover{
    color:#fff;
    background: #6AAC70; /* Pagination background on hover */
}
 
.pagination .current{
    padding:6px 9px 5px 9px;
    background: #6AAC70; /* Current page background */
    color:#fff;
}

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

Функция Pagination

Код ниже – это весь код, который требуется нам для того, чтобы пагинация корректно работала. Именно здесь обрабатываются возвращенные данные запроса и формируется наша красивая пагинация. Скопируйте и вставьте этот код в ваш файл functions.php. Никаких изменений совершать не нужно:

<?php
// numbered pagination
function pagination($pages = '', $range = 4)
{  
     $showitems = ($range * 2)+1;  
 
     global $paged;
     if(empty($paged)) $paged = 1;
 
     if($pages == '')
     {
         global $wp_query;
         $pages = $wp_query->max_num_pages;
         if(!$pages)
         {
             $pages = 1;
         }
     }   
 
     if(1 != $pages)
     {
         echo "<div class=\"pagination\"><span>Page ".$paged." of ".$pages."</span>";
         if($paged > 2 && $paged > $range+1 && $showitems < $pages) echo "<a href='".get_pagenum_link(1)."'>&laquo; First</a>";
         if($paged > 1 && $showitems < $pages) echo "<a href='".get_pagenum_link($paged - 1)."'>&lsaquo; Previous</a>";
 
         for ($i=1; $i <= $pages; $i++)
         {
             if (1 != $pages &&( !($i >= $paged+$range+1 || $i <= $paged-$range-1) || $pages <= $showitems ))
             {
                 echo ($paged == $i)? "<span class=\"current\">".$i."</span>":"<a href='".get_pagenum_link($i)."' class=\"inactive\">".$i."</a>";
             }
         }
 
         if ($paged < $pages && $showitems < $pages) echo "<a href=\"".get_pagenum_link($paged + 1)."\">Next &rsaquo;</a>";  
         if ($paged < $pages-1 &&  $paged+$range-1 < $pages && $showitems < $pages) echo "<a href='".get_pagenum_link($pages)."'>Last &raquo;</a>";
         echo "</div>\n";
     }
}
?>

Вывод числовой пагинации в WordPress

Теперь, когда все настроено, мы можем вывести пагинацию на сайте. Добавьте следующий блок кода напрямую в свою тему или шаблон (в зависимости от того, где именно нужно вывести пагинацию).

<?php if (function_exists("pagination")) {
    pagination($custom_query->max_num_pages);
} ?>

Ваша пагинация в WordPress будет иметь следующий вид:

pagination_screenshot

Источник: www.evan-herman.com

Блог про WordPress
Комментарии: 25
  1. Анатолий

    А вот скажите, действительно ли это будет нагружать систему меньше, чем плагин? И вообще поддерживаете ли вы мнение о том, что плагины гораздо тяжелее, чем их замена кодом, и что они безумно тормозят WordPress-сайт?

    1. Дмитрий (автор)

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

  2. Дмитрий

    Здравствуйте, сделал пагинацию по вашему мануалу и добавил еще ajax, как мне теперь добавить якорь чтоб при переходе отображение поднималось к началу контента, ссылка airbagcar.ru/cat/raboty

    1. Дмитрий (автор)

      Хм, интересный вопрос. Даже не знаю, что и посоветовать. Если только создать закладку через тот же тег a, и потом как-то его прикрутить к коду. Но как это реализовать, честно сказать, не представляю…

  3. andrew

    Здравствуйте. Можно ли применить ваш код для пагинации на странице с изображениями? Т.е. контент страницы — только вложения картинок.

    1. Дмитрий (автор)

      Придется переписывать код, создавать цикл для получения страниц вложений через WP_Query. Вот здесь можно получить примерное представление:

      http://wordpress.stackexchange.com/questions/15163/broken-wp-query-and-attachment-as-a-post-type

  4. andrew

    Почему-то получаю max_num_pages = 0.

  5. andrew

    Все получилось, спасибо.

  6. Константин

    Всё работает, но как поменять количество выводимых постов на странице?

    1. Дмитрий (автор)

      Через Настройки — Чтение в панели администратора.

      1. Константин

        Спасибо. А если надо будет на разных страницах разное кол-во записей выводить, то в цикле нельзя аргумент поменять?

  7. Дмитрий (автор)

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

    http://wordpress.stackexchange.com/questions/155758/have-different-number-of-posts-on-first-page

  8. артем

    в последнем коде я бы поставил вместо custom_query вот это — wp_query, тем самым устраняем предупреждение при отладке кода — «функции пытаются получить свойство несуществующего объекта».

  9. Николай

    Хорошо отработала Ваша функция пагинации, спасибо

  10. Сергей

    Подскажите, почему стили (взятые из Вашего примера и внедренные в файл style.css моей темы WP) блоков, описываемых в функции pagination, которую я вставил в файл functions.php, могут не применяться к этим блокам при просмотре сайта? Как будто их вообще нет. Для проверки вставлял описание стилей в файл functions и все работало. В чем может быть моя ошибка?

    1. Дмитрий (автор)

      Стили вставляете в самый низ файла? Бывает, что переписываются другими стилями.

      1. Сергей

        Да. Стили вставлял в самый низ файла style.css. Просмотр стилей через встроенный инструмент браузера показывает, что свойства стилей наследуются от общего стиля страницы (параметры шрифта, отступы, выравнивание и пр.) и от стиля обрамляющего блока div, а те стили, которые специально созданы для указанных объектов ‘span’ и ‘а’ вообще нигде не упоминаются.

  11. Дмитрий (автор)

    Есть несколько вариантов. 1. Попробуйте вообще вставить какие-либо стили в этот файл и проверить на практике, будут ли они работать.
    2. Возможно, у вас стоит плагин кэширования, и потому надо сначала очистить кэш, чтобы увидеть изменения.

  12. Сергей

    а как добавить показать все/всё отдельной кнопкой/ссылкой?

    1. Дмитрий (автор)

      Придется думать, как вписать все это в текущую разметку, чтобы все не разъехалось.

      Можно воспользоваться советами тут:

      http://www.wpbeginner.com/wp-tutorials/how-to-display-all-your-wordpress-posts-on-one-page/

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

  13. Наталья

    Сделала. Получилось красиво. Но почему-то последнюю страницу https://nataliablogs.ru/page/48/
    через w3 не обрабатывает — IO Error: HTTP resource not retrievable. The HTTP status from the remote server was: 404.
    Document checking not completed. The result cannot be determined due to a non-document-error.
    Из-за чего такое может быть?

  14. Ярослав

    Здравствуйте, все заработало. Спаибо большое.
    Но я не могу понять как вывести записи из одной определенной рубрики. Подскажите как это сделать, пожалуйтса

    1. Ярослав

      разобрался)

  15. Вова

    а у меня с шаблоном SpicePress не работает!

    1. Дмитрий (автор)

      Не во всех шаблонах нормально работает, к сожалению.

Добавить комментарий для Константин Отменить ответ

Получать новые комментарии по электронной почте.