
Попалась мне как-то тема, что популярнейший среди Wordpress'цов плагин wp-pagenavi грузит сервер не в меру своей надобности. Проанализировав его код скажу, что это в общем не правда, хотя лишнее там есть и именно этому посвящен этот пост.
За удобство надо платить. Wp-pagenavi, как и другие плагины этому подтверждение - за удобство настроек в админ панели приходится платить, ценой лишних запросов к данным, так как эти настройки сохраняются в Базу данных, а затем от туда и берутся, хотя это в теории, а на практике они берутся из кеша таблицы wp-options, размер которого всегда больше 300кб и обращаться к этому файлу кеша желательно как можно меньше ИМХО.
Если другие плагины сложно представить без возможности их настройки в админ панели, то wp-pagenavi мне представляется очень легко. Лично мне достаточно один раз настроить навигацию и забыть про нее навек, думаю у многих так, поэтому я решил отказаться от незаменимого плагина wp-pagenavi и заменить его на свою функцию, которую можно настроить в файле шаблона. Функцию я написал, предварительно изучив код WP-pagenavi, частями позаимствовал от туда код, поэтому все css классы wp-pagenavi сохранены и как следствие заменить wp-pagenavi на мой вариант не составит никакого труда.
Для замены нужно скопировать нижеследующую функцию в файл шаблона functions.php. А так же, скопировать css стили WP-pagenavi в ваш файл css (обычно с названием style.css). Объединение css стилей, тоже полезно - минус одно обращение к серверу.
/* Альтернатива wp_pagenavi (без лишних обращений к данным)
------------------------------------------------------------------------------ */
function kama_pagenavi($before='', $after='', $echo=true) {
/* ================ Настройки ================ */
$text_num_page = ''; // Текст для количества страниц. {current} заменится текущей, а {last} последней. Пример: 'Страница {current} из {last}' = Страница 4 из 60
$num_pages = 10; // сколько ссылок показывать
$stepLink = 10; // после навигации ссылки с определенным шагом (значение = число (какой шаг) или '', если не нужно показывать). Пример: 1,2,3...10,20,30
$dotright_text = '…'; // промежуточный текст "до".
$dotright_text2 = '…'; // промежуточный текст "после".
$backtext = '« назад'; // текст "перейти на предыдущую страницу". Ставим '', если эта ссылка не нужна.
$nexttext = 'вперед »'; // текст "перейти на следующую страницу". Ставим '', если эта ссылка не нужна.
$first_page_text = '« к началу'; // текст "к первой странице" или ставим '', если вместо текста нужно показать номер страницы.
$last_page_text = 'в конец »'; // текст "к последней странице" или пишем '', если вместо текста нужно показать номер страницы.
/* ================ Конец Настроек ================ */
global $wp_query;
$posts_per_page = (int) $wp_query->query_vars[posts_per_page];
$paged = (int) $wp_query->query_vars[paged];
$max_page = $wp_query->max_num_pages;
if($max_page <= 1 ) return false; //проверка на надобность в навигации
if(empty($paged) || $paged == 0) $paged = 1;
$pages_to_show = intval($num_pages);
$pages_to_show_minus_1 = $pages_to_show-1;
$half_page_start = floor($pages_to_show_minus_1/2); //сколько ссылок до текущей страницы
$half_page_end = ceil($pages_to_show_minus_1/2); //сколько ссылок после текущей страницы
$start_page = $paged - $half_page_start; //первая страница
$end_page = $paged + $half_page_end; //последняя страница (условно)
if($start_page <= 0) $start_page = 1;
if(($end_page - $start_page) != $pages_to_show_minus_1) $end_page = $start_page + $pages_to_show_minus_1;
if($end_page > $max_page) {
$start_page = $max_page - $pages_to_show_minus_1;
$end_page = (int) $max_page;
}
if($start_page <= 0) $start_page = 1;
$out='';//выводим навигацию
$out.= $before."<div class='wp-pagenavi'>\n";
if ($text_num_page){
$text_num_page = preg_replace ('!\{current\}|\{last\}!','%s',$text_num_page);
$out.= sprintf ("<span class='pages'>$text_num_page</span>",$paged,$max_page);
}
if ($backtext && $paged!=1) $out.= '<a href="'.get_pagenum_link(($paged-1)).'">'.$backtext.'</a>';
if ($start_page >= 2 && $pages_to_show < $max_page) {
$out.= '<a href="'.get_pagenum_link().'">'. ($first_page_text?$first_page_text:1) .'</a>';
if($dotright_text && $start_page!=2) $out.= '<span class="extend">'.$dotright_text.'</span>';
}
for($i = $start_page; $i <= $end_page; $i++) {
if($i == $paged) {
$out.= '<span class="current">'.$i.'</span>';
} else {
$out.= '<a href="'.get_pagenum_link($i).'">'.$i.'</a>';
}
}
//ссылки с шагом
if ($stepLink && $end_page < $max_page){
for($i=$end_page+1; $i<=$max_page; $i++) {
if($i % $stepLink == 0 && $i!==$num_pages) {
if (++$dd == 1) $out.= '<span class="extend">'.$dotright_text2.'</span>';
$out.= '<a href="'.get_pagenum_link($i).'">'.$i.'</a>';
}
}
}
if ($end_page < $max_page) {
if($dotright_text && $end_page!=($max_page-1)) $out.= '<span class="extend">'.$dotright_text2.'</span>';
$out.= '<a href="'.get_pagenum_link($max_page).'">'. ($last_page_text?$last_page_text:$max_page) .'</a>';
}
if ($nexttext && $paged!=$end_page) $out.= '<a href="'.get_pagenum_link(($paged+1)).'">'.$nexttext.'</a>';
$out.= "</div>".$after."\n";
if ($echo) echo $out;
else return $out;
}
Настройки описаны прямо в коде, они идентичны настройкам самого wp-pagenavi, с той лишь разницей, что вместо текста "к последней странице" можно вывести номер последней страницы.
После того, как функция установлена и css плагина перенесен меняем в шаблоне код wp_pagenavi на этот:
<?php kama_pagenavi(); ?>
Если у вас в коде что-то вроде этого: if(function_exists('wp_pagenavi')) { wp_pagenavi('<center>','</center>'); , то просто поменять все wp_pagenavi на kama_pagenavi.
Если навигация выводится 2 раза
Так же, хочу обратить внимание тех, у кого навигация выводится 2 раза на странице (сверху и снизу цикла). Чтобы 2 раза не выполнять одни и те же операции по составлению навигации, логичнее сделать так: одни раз собрать навигацию (использовать функцию), затем записать результат в переменную и второй раз просто вывести эту переменную. Выглядит это так:
// место, где первый раз нужно вывести навигацию
// получаем навигацию и записываем её в переменную
$get_navigation = kama_pagenavi('', '', false);
// выводим переменную на экран
echo $get_navigation;
/* Здесь идет вывод постов - цикл Loop */
// место, где второй раз нужно вывести навигацию.
//Так как навигация уже записана в переменную $get_navigation, её можно просто вывести на экран.
echo $get_navigation;
Обновление 2.05.2010
- Добавлены ссылки назад/вперед, пример:
«к началу «назад ... 11 12 13 14 15 16 17 18 ... вперед» в конец»
Их можно отключить (см. настройки). - Убран баг такого типа:
1 ... 2 3 4 5 6 7 8 ... 50 или 1 ... 21 22 23 24 25 26 27 28 ... 29
То есть, где не нужно убраны тексты "до" и "после" навигации (в данном примере это троеточие).
Обновление 11.05.2010
Перенес ссылки назад/вперед, теперь так:
«назад «к началу ... 11 12 13 14 15 16 17 18 ... в конец» вперед»
Последний вариант функции наверху.
Реверсивная пагинация для WordPress
Идея реверсивной (обратной) пагинации принадлежит некоему sholo, который высказал её на известном нам форуме - mywordpress.ru (ссылка на ветку). Мне стало интересно посмотреть, как это будет выглядеть и я немного переделал код. Вот что получилось:
А вот собственно и код, для тех кто хочет сделать себе такую пагинацию:
/* Альтернатива wp_pagenavi - реверсивная пагинация
--------------------------------------------------------------------------------- */
function kama_pagenavi($before='', $after='', $echo=true) {
/* ================ Настройки ================ */
$text_num_page = ''; // Текст для количества страниц. {current} заменится текущей, а {last} последней. Пример: 'Страница {current} из {last}' = Страница 4 из 60
$num_pages = 10; // сколько ссылок показывать
$stepLink = 10; // после навигации ссылки с определенным шагом (значение = число (какой шаг) или '', если не нужно показывать). Пример: 1,2,3...10,20,30
$dotright_text = '…'; // промежуточный текст "до".
$dotright_text2 = '…'; // промежуточный текст "после".
$backtext = '<<<'; // текст "перейти на предыдущую страницу". Ставим '', если эта ссылка не нужна.
$nexttext = '>>>'; // текст "перейти на следующую страницу". Ставим '', если эта ссылка не нужна.
$first_page_text = '« последняя'; // текст "к первой странице" или ставим '', если вместо текста нужно показать номер страницы.
$last_page_text = 'первая »'; // текст "к последней странице" или пишем '', если вместо текста нужно показать номер страницы.
/* ================ Конец Настроек ================ */
global $wp_query;
$posts_per_page = (int) $wp_query->query_vars[posts_per_page];
$paged = (int) $wp_query->query_vars[paged];
$max_page = $wp_query->max_num_pages;
if($max_page <= 1 ) return false; //проверка на надобность в навигации
if(empty($paged) || $paged == 0) $paged = 1;
$pages_to_show = intval($num_pages);
$pages_to_show_minus_1 = $pages_to_show-1;
$half_page_start = floor($pages_to_show_minus_1/2); //сколько ссылок до текущей страницы
$half_page_end = ceil($pages_to_show_minus_1/2); //сколько ссылок после текущей страницы
$start_page = $paged - $half_page_start; //первая страница
$end_page = $paged + $half_page_end; //последняя страница (условно)
if($start_page <= 0) $start_page = 1;
if(($end_page - $start_page) != $pages_to_show_minus_1) $end_page = $start_page + $pages_to_show_minus_1;
if($end_page > $max_page) {
$start_page = $max_page - $pages_to_show_minus_1;
$end_page = (int) $max_page;
}
if($start_page <= 0) $start_page = 1;
$out='';//выводим навигацию
$out.= $before."<div class='wp-pagenavi'>\n";
if ($text_num_page){
$text_num_page = preg_replace ('!\{current\}|\{last\}!','%s',$text_num_page);
$out.= sprintf ("<span class='pages'>$text_num_page</span>",$paged,$max_page);
}
if ($backtext && $paged!=1) $out.= '<a href="'.get_pagenum_link(($paged-1)).'">'.$backtext.'</a>';
if ($start_page >= 2 && $pages_to_show < $max_page) {
$out.= '<a href="'.get_pagenum_link().'">'. ($first_page_text?$first_page_text:$max_page) .'</a>';
if($dotright_text && $start_page!=2) $out.= '<span class="extend">'.$dotright_text.'</span>';
}
for($i = $start_page; $i <= $end_page; $i++) {
if($i == $paged) {
$out.= '<span class="current">'.($max_page-$i+1).'</span>';
} else {
$out.= '<a href="'.get_pagenum_link($i).'">'.($max_page-$i+1).'</a>';
}
}
//ссылки с шагом
if ($stepLink && $end_page < $max_page){
for($i=$end_page+1; $i<=$max_page; $i++) {
if($i % $stepLink == 0 && $i!==$num_pages) {
if (++$dd == 1) $out.= '<span class="extend">'.$dotright_text2.'</span>';
$out.= '<a href="'.get_pagenum_link($i).'">'.($max_page-$i+1).'</a>';
}
}
}
if ($end_page < $max_page) {
if($dotright_text && $end_page!=($max_page-1)) $out.= '<span class="extend">'.$dotright_text2.'</span>';
$out.= '<a href="'.get_pagenum_link($max_page).'">'. ($last_page_text?$last_page_text:1) .'</a>';
}
if ($nexttext && $paged!=$end_page) $out.= '<a href="'.get_pagenum_link(($paged+1)).'">'.$nexttext.'</a>';
$out.= "</div>".$after."\n";
if ($echo) echo $out;
else return $out;
}
Верхний и этот коды можно заменять, потому что они одинаковы, меняются только числа (цыфры).
Чтобы не искать css стили ниже стандартные стили wp-pagenavi, которые нужно добавить в ваш файл стилей.
.wp-pagenavi a, .wp-pagenavi a:link {
padding: 2px 4px 2px 4px;
margin: 2px;
text-decoration: none;
border: 1px solid #0066cc;
color: #0066cc;
background-color: #FFFFFF;
}
.wp-pagenavi a:visited {
padding: 2px 4px 2px 4px;
margin: 2px;
text-decoration: none;
border: 1px solid #0066cc;
color: #0066cc;
background-color: #FFFFFF;
}
.wp-pagenavi a:hover {
border: 1px solid #000000;
color: #000000;
background-color: #FFFFFF;
}
.wp-pagenavi a:active {
padding: 2px 4px 2px 4px;
margin: 2px;
text-decoration: none;
border: 1px solid #0066cc;
color: #0066cc;
background-color: #FFFFFF;
}
.wp-pagenavi span.pages {
padding: 2px 4px 2px 4px;
margin: 2px 2px 2px 2px;
color: #000000;
border: 1px solid #000000;
background-color: #FFFFFF;
}
.wp-pagenavi span.current {
padding: 2px 4px 2px 4px;
margin: 2px;
font-weight: bold;
border: 1px solid #000000;
color: #000000;
background-color: #FFFFFF;
}
.wp-pagenavi span.extend {
padding: 2px 4px 2px 4px;
margin: 2px;
border: 1px solid #000000;
color: #000000;
background-color: #FFFFFF;
}
Неплохую подборку стилей можно подглядеть здесь
.
Все вопросы и предложения с нетерпением жду в комментариях.
- Предыдущие по меткам
- Предыдущие записи
- Функция вывода записей по количеству просмотров ← 5.Июл.2010 // 46
- Сравнение СЕО плагинов platinum SEO Pack и All in One SEO Pack и отказ от них ← 24.Май.2010 // 15
- Считаем количество посещений страниц на WordPress без плагинов ← 21.Апр.2010 // 25
- Подсветка результатов поиска, без использования плагинов ← 17.Апр.2010 // 4
- Код на страницах вашего сайта. Как я решил эту проблему ← 26 марта 2010 // 4
- Плагин для легкого управления сайтом на WordPress (версия 3) ← 30 июля 2010 // 10
- Обзор WordPress 3.0. Что несет нам прогресс? ← 30 июля 2010 // 1
Я не знаю php вообще, как сделать так?

Вам к Лебедеву нужно обратиться
Шутка.
Если php не знаете, то делайте так, как предлагается и не нужно подражать батюшке Яндексу
А я сделал
Хотелось чтобы на php сделалось примерно так:
я уже кое-что начал понимать
итак, я тут делаю и мне нужно вот это
поместить внутрь этого дива
но не знаю как это сделать, помогите
Получилось)
Незнаю насколько логичен такой код, поправьте если это неправильно ну и все такое
еще было классно если бы ссылка на несуществующую страницу не исчезала, а становилась обычным текстом как на картинке

Я считаю что без такой "нерабочей ссылки" глазам человека непривычно
так вроде нужно чтоб визуально не нарушалоась привычность навигации ссылками "предыдущая", "следующая"
когда пропадает ссылка, я начинаю тупить)
Можно так сделать (исправленный код, который вы выложили выше, с учетом, чтобы назад/вперед не исчезали, если ссылки нет, то будет просто текстом показываться):
Спасибо!
я еще стрелочек и надпись "страницы" добавил
Не знаю как это заработало, но я что-то неправильно с стрелочками сделал
$out='';//выводим навигацию $out.= $before."<div class='wp-pagenavi'>\n"; $out.= "<div class='wp-kama-navi'>"; if ($text_num_page){ $text_num_page = preg_replace ('!\{current\}|\{last\}!','%s',$text_num_page); $out.= sprintf ("<b>$text_num_page</b> ",$paged,$max_page); } $out.= ($backtext && $paged!=1) ? '←<a href="'.get_pagenum_link(($paged-1)).'">'.$backtext.'</a>' : '← ' .$backtext; $out.= ($nexttext && $paged!=$end_page) ? '<a href="'.get_pagenum_link(($paged+1)).'">'.$nexttext.'</a>→' : ''.$nexttext.' →' ; $out.= "</div>";