Выбросьте PageNavi|Как быстро сделать пагинацию

Вы все еще пользуетесь плагином WP-PageNavi? И вам не плевать, что он подключает дополнительный CSS, грузит сервер, выцепляет ненужные переменные и пользует дополнительные настройки? Хех, ну тогда дальше текст не про вас.

Мне вполне нравится, как построена структура шаблонов темы в Wordpress. С помощью нее можно такого наворотить — вплоть до разного оформления у особых страниц, архивов и категорий. Но эта избыточность при создании темы требует немного более внимательно следить, если необходимо создать адекватную и однообразную тему. Именно поэтому в файлах index.php, archives.php, category.php и tags.php у меня разный только заголовок, а циклический вывод страниц (т.к. он абсолютно одинаков), я бы посоветовал вынести в отдельный файл (например, content.php) и уже в нем делать стандартный вывод:

<div id="content">
	<?php while (have_posts()) : the_post(); ?>
	<div class="post" id="post-<?php the_ID(); ?>">
	...

Ну и так далее. Соответственно, в single.php и page.php эти куски будут своими.

Такой подход позволяет легко сделать и нормальную пагинацию, не обращаясь к тормозному PageNavi. Все что нам надо — в <div class="navigation"> именно в новом файле использовать стандартные функции Wordpress.

Есть функции previous_posts() и next_posts_link(), которые выводят ссылки на предыдущие и следующие страницы, есть более широкая по функциональности posts_nav_link(), которая умело справляется с определением необходимости вывода разделителя и ссылок — только тогда, когда предыдущая страница или следующая существуют.

Но всем тем, кто жаждет лучшей индексации страниц и больше бабла от САПы (удобство для посетителей блога, конечно, тоже присутствует, но в меньшей мере), нужно больше, вот они и ставят плагин. А ведь все функции есть и в самом ВП, достаточно только поработать с самой темой.

Все достаточно просто — скажем, создадим отдельный файл под эту часть темы, и подключим, как обычно, через include_once в нужном месте content.php. В самом же файле нам надо:

  1. Узнать, сколько у нас страниц вообще.
  2. Если не одна, то узнать, какая из них текущая.
  3. Вывести «Самая первая» ссылкой, если она — не текущая.
  4. Определить начало вывода ссылок (текущая минус максимальное количество для вывода) на страницы и проверить, если между первой и начальной есть еще страницы, поставить троеточие.
  5. В цикле вывести все странички до конечной.
  6. Конечная высчитывается (текущая плюс максимум) и, в случае необходимости, опять же ставится троеточие.
  7. И заканчиваем «Самой последней» страницой.

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

<?php
global $wp_query;
$max_page = $wp_query->max_num_pages;
$nump=10;

if($max_page!=1){
	$paged = intval(get_query_var('paged'));
	if(empty($paged) || $paged == 0) $paged = 1;

	echo '<p class="pagenavi">';

	if($paged!=1) echo '<a href="'.get_pagenum_link(1).'">First</a> ';
		else echo '<span class="current">First</span> ';

	if($paged-$nump>1) $start=$paged-$nump; else $start=2;
	if($paged+$nump<$max_page) $end=$paged+$nump; else $end=$max_page-1;

	if($start>2) echo "... ";

	for ($i=$start;$i<=$end;$i++)
	 {
	 if($paged!=$i) echo '<a href="'.get_pagenum_link($i).'">'.$i.'</a> ';
		else echo '<span class="current">'.$i.'</span> ';
	 }

	if($end<$max_page-1) echo "... ";

	if($paged!=$max_page) echo '<a href="'.get_pagenum_link($max_page).'">Last</a>';
		else echo '<span class="current">Last</span> ';
	echo '</p>'	;
	}
?>

Соответственно, вместо Last и First используете свой текст (или цифры), не забывая экранировать его. Спан с классом current определяете в CSS или просто заменяете на strong. Ну и совмещаете с стандартным функциями следующая-предыдущая при необходимости.

В переменной nump — количество выводимых страниц слева и справа от текущей (и, соответственно, генерируемое число страниц 2го уровня минус 2). Т.е. максимальное количество, которое будет отображено — это nump*2, следите внимательно, чтобы не уплыло за края блока.

Получается что-то вроде этого:

Навигация своими силами

И все — без всяких там плагинов.

{44 комментария} Подписка на комментарии

Вот за это, между прочим, большое спасибо. Navi действительно тот ещё тормоз.

Надо попробовать. Рекомендую сделать в виде файла, который можно просто скачать и к которому достаточно прописать путь в других файлах. А то многим создание нового файла покажется слишком сложным. А если быстрее будет работать, то штука нужная и полезная.

Уже за меня сделали — blognoble.net/2008_10_05/...ezhde-vsego.html . Вот только не знаю, там сохранено ли в UTF-8, или нет.

Мне лично не особо интересны люди, которые не могут вручную подобное сделать. Лень — вообще омерзительная штука :)

Спасибо за гайд, замутил у себя.

Опубликовал на sociall.ru. надеюсь не против :)

Да конечно. На мой взгляд, блоги существуют для того, чтобы ссылаться на интересные себе вещи, а ссылки — для того, чтобы ставить их без всяких расширений.

А давыдовские полупосты становятся популярными :). Вот только бы я тебе посоветовал пользоваться ими по-другому — blockquote и прочее оформление нещадно ужасно — можно, скажем, отделять вводный текст от далее <hr />, цитату — обычным текстом, но где-то на середине обрывать фразу, подсвечивая ее и ставя многоточие или стрелочку. А анкором делать последний значащий кусок текста.

Ну первый блин комом ) в дальнейшем будет лучше. Кстати подписался. Инфа довольна для меня интересная, думаю часто мелькать будешь на социалле)

Ну что я могу сказать — спасибо. Я тоже умею плюшки раздавать направо и налево, так что не пропустишь. :)

Сделал квадратики как у pagenavi. Тупо скопипастил.

Снес page-navi и воспользовался советом из данного поста (правда прочитал на другом блоге) и хочу поинтересоваться: у меня стоят плагины, отображающие скорость обработкаи запросов к БД и объем используемой памяти. Судя по этим плагинам, нагрузка осталась на том же уровне, как так? Или они не показатель?

Хыхы, прикольный анкорчик.

Запрос к БД всего один (там вроде как 2), но не используется: механизм подключения плагинов, хранения настроек в базе данных, код более прост и чист. К тому же, не подключается дополнительный CSS — на один меньше HTTP-запрос.

Конечно, это требует какое-тог усилие, да, превозмочь лень. Зато решение легко изменяемо, масштабируемо и не избыточно. Вот и все.

Ок, теперь все понял. Кстати, по любому установка не сложнее активации и настройки плагина PN. Спасибо за инструкцию.

Любопытная штуковина. Попробую тож поковырять. Только зачем создавать новый файл? Можно ведь использовать стандартный home.php.

Скажем так, лучше выделять такую функциональность в теме, в отдельные файлы. Точно так же у менея выделен блогокуб, свежие и популярные посты, и даже форма комментария из comments.php. Потом в хаосе разбираться — себе дороже.

А, ну если только для порядка. Блогокуб, кстати, заинтересовал сильно. Напиши, пожалуйста, пост о его реализации?

@Василий Сухов: что именно тебя в нем интересует? Там все просто — подготовлены и ужаты сами баннеры, залиты на гугл.

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

Сами изображения вставляются в табличку — чтобы не допустить «сваливания». Подставляются либо случайно (выбирается номер как mt_rand (0,$num-1)), или псевдослучайно — на страницах и записях. Генератор тут тоже простой, хотя и кривоват:

$l = (pow (get_the_id (),2)/3+pow ($k,6)/5) % $num;

Есть куча плагинов для встваки баннеров — не вижу смысла описывать то, что не будет понятно :)

Да, для меня это, пожалуй, будет сложновато. Лучше и впрямь плагин какой-нибудь попользовать :)

Но выглядит здорово! А главное — удобно. Можно не ограничиваться в количестве ссылок в блогролле.

только сегодня руки дошли до ручной пагинации, оказалось в моей теме автор вообще вывод навигации по страницам сделал в отдельном файле browse.php

Спасибо за решение, а я-то думал, что wordpress настроил окончательно.

Замечательное решение, вот только стрелка «в будущее», указывающая влево, — семантический шок для мозга любого по-европейски воспитаного человека. Товарищи, «будущее» у нас всегда справа — представляя временную шкалу, мы движемся вправо от условного нулевого отрезка и наоборот (для «влево») соответственно. Тлетворное влияние аниме? :-)

Вот вы пишите, что WP-PageNavi тормозит. А в каком месте он тормозит? Как это проявляется? Не один год им пользуюсь и ни разу не замечал того, что позволило бы сделать такой вывод.

@Dimox: писалось давно, без адекватных тестов. Но — есть четыре основных пункта, в какой-то мере являющиеся «спичками», на которых хорошо бы сэкономить. Это подключение плагина как таковое, лишние телодвижения в коде (ну, на нормальных серверах это почти ничего), хранение настроек в базе (несмотря на кеширование запросов самим ВП, это лишнее) и отдельный CSS (нагрузка на клиентскую часть) — который в большинстве случаев совершенно не подходит остальному дизу блога.

Но самое главное — в моем представлении, парадигма шаблонов предполагает то, что пагинация должна изначально быть в шаблонной части вывода, т.к. не является по сути «дополнительным функционалом», хотя и содержит обработку данных, а не чистый вывод.

К этой теме, наверное, надо бы еще вернуться.

Ясно. Спасибо за подробный ответ. Соглашусь на 100% только по поводу CSS. У себя на блоге деактивировал в плагине подключение дополнительного файла, а все стили перенес в основной CSS-файл. И именно по этой же причине я в одном из своих плагинов предусмотрел опциональное подключение стилей плагина.

> что пагинация должна изначально быть в шаблонной части вывода, т.к. не является по сути «дополнительным функционалом»

Согласен. Это, кстати, касается многих функций, которые давно существуют в виде плагинов, хотя очевидно, что они должны присутствовать по умолчанию.

P.S. В общем, надо будет обязательно попробовать твой вариант пагинации =) Спасибо.

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

Попробовал эту пагинацию. Понравилось =) Поэтому большое спасибо! Не хуже WP-PageNavi =)))

Неплохая идея, но смотрится немного пресновато. Я на своих блогах lifeinfo.co.cc и infopress так же делаю пагинацию посредством темы, но смотрится намного красивее. Индексируется тоже на ура. Кому интересно, мыльте, поделюсь.

@Simon: какая разница, как оформлять? CSS в руки и сверстай себе под собственный дизайн.

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

Сергей, можешь ли ты написать аналогичный код для пагинации в комментариях, которая в WP 2.7+?

@Dimox: можно посмотреть, смотря как там это сделано (и, кстати, вроде у нативной пагинации комментов есть какие-то проблемы).

Dimox, если тебе еще актуально: посмотри в сторону paginate_comments_links ().

Я у себя на блоге сделал так (вариант неокончательный, пока тестирую):

'list', 'prev_next' => false)); ?>

Вроде бы работает.

Блин, WordPress всё съел :- (

<div class="navigation paging">
        <div class="alignleft"><?php previous_comments_link('« Старые комментарии'); ?></div>
        <?php paginate_comments_links(array('type' => 'list', 'prev_next' => false)); ?>
        <div class="alignright"><?php next_comments_link('Новые комментарии »'); ?></div>
    </div>

Vladimir, актуально. Спасибо большое!

Добрый день, поставил Вашу замечательную фичу. Но возникла небольшая проблема. Когда я нажимаю на рубрику у себя на сайте, или задаю автора по посковику, где более 10 постов, у меня внизу высвечивается пагинация. Но как только я нажимаю на 2-ю страницу — мне выдает ошибку 404. На самом сайте при перелистывании страниц, проблем нет. Подскажите пожалуйста в чем может быть проблема. Заранее Спасибо.

Это оттого, что неправильно задана структура пермалинков на категории. Точнее, правильно с точки зрения логики, но ВП не понимает конструкции uzhasov.net/barker/page/2/, зато прекрасно работает с uzhasov.net/category/barker/page/2/

При этом, конечно, он автоматически такие пермалинки делает, но не понимает. Увы.

Спасибо большое за ответ. Буду думать.

Спасибо за статью.

А как сделать пагинацию произвольных списков?

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

Пост заслуживает внимания однозначно!

Но глядя на код плагина WP pagenavi v2.31. Там по сути сделано тоже самое, только, совсем чуть расширенее и с учетом настроек плагина.

Я например не нашел там ничего такого, что делает код «грузовее», чем этот, конечно если не считать получение настроек, которые делаются в админке.

Авторуреспект. Сейчас попробую как альтернативу PageNavi. И ксати вышел в свет уже PageNavi 2.72 в нем насчет использования ресурсов уже спорный вопрос. Так что советую присмотреться.

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

Попробовал ваше решение проблемы пагинации на сайте, но столкнулся с одной проблемой, которую кстати не нашел в WP-Pagenavi. А именно, у меня на сайте в данный момент, насчитывается 29 страниц, в вашем скрипте я выставляю $nump=10; — пробую ходить по страницам, наживая на их номера внизу сайта выведенные через данный скрипт.

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

Заранее спасибо

У меня вопрос в оформлении, очень понравилось решения замены плагинов, но как можно заменит хоть что-то?) стиль вообще не подходит... У меня это первый сайт и только начал разбираться во всем этом, помогите...

У меня вопрос в оформлении, очень понравилось решения замены плагинов, но как можно заменит хоть что-то?) стиль вообще не подходит... У меня это первый сайт и только начал разбираться во всем этом, помогите...

мне никто не поможет?(

Стиль — это о CSS. Пользуйтесь готовыми решениями.

А здесь можно оставить свое мнение ↓ Подписка на комментарии
какие-то из следующих трех полей можно оставить пустыми


нет тегам!!! **эмоция**, __ирония__, >цитата, {[код]}