
Попалась мне как-то тема, что популярнейший среди WordPress'цов плагин wp-pagenavi грузит сервер не в меру своей надобности. Проанализировав его код выяснил что все это сказки, хотя лишнее там есть и именно этому посвящен этот пост.
За удобство надо платить. Wp-pagenavi, как и другие плагины этому подтверждение — за удобство настроек в админ панели приходится платить, ценой лишних запросов к данным, так как эти настройки сохраняются в Базу данных, а затем от туда и берутся, хотя это в теории, а на практике они берутся из кэша опций WordPress — процесс моментальный.
Если другие плагины сложно представить без возможности их настройки в админ панели, то wp-pagenavi мне представляется очень легко. Лично мне достаточно один раз настроить навигацию и забыть про нее навек. Я же не один такой? Поэтому я решил отказаться от обязательного плагина wp-pagenavi и заменить его на свою функцию, которую нужно настроить в файле шаблона. Функцию я написал, предварительно изучив код WP-pagenavi, частями позаимствовал от туда код, поэтому все CSS классы wp-pagenavi сохранены и как следствие, заменить wp-pagenavi на мой вариант не составит никакого труда.
Для замены нужно скопировать нижеследующую функцию в файл шаблона functions.php. А так же, скопировать CSS стили WP-pagenavi в ваш файл стилей (обычно это 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;
}
Неплохую подборку стилей можно подглядеть здесь
.
Все вопросы и предложения с нетерпением жду в комментариях.
- Предыдущие по меткам
- Предыдущие записи
- Самые Хлебные крошки (breabcrumbs для WordPress) ← 19.Апр.2011 // 79
- Функция вывода постов по количеству комментариев (самый комментируемые записи в WordPress) ← 25.Ноя.2010 // 22
- Функция вывода записей по количеству просмотров ← 5.Июл.2010 // 118
- Сравнение СЕО плагинов platinum SEO Pack и All in One SEO Pack и отказ от них ← 24.Май.2010 // 73
- Код на страницах вашего сайта. Как я решил эту проблему ← 26 Март 2010 // 23
- Произвольные типы записей и таксономии в виджете "Прямо сейчас" + плагин ← 1 Октябрь 2011 // 4
- 20+ полезных SQL запросов для WordPress ← 14 Сентябрь 2011 // 11
проблема при настройке плагина прикрепляю скриншот
как решить?
http://narod.ru/disk/7645451001/1.jpg.html
Добрый день. Не подскажете, как можно прикрутить эту функцию (или более простую пагинацию) к списку анонсов комментариев, вызванных из базы таким вот кодом:
<?php global $wpdb; $sql = "SELECT DISTINCT ID, post_title, post_password, comment_ID, comment_post_ID, comment_author, comment_author_email, comment_date_gmt, comment_approved, comment_type,comment_author_url, SUBSTRING(comment_content,1,200) AS com_excerpt FROM $wpdb->comments LEFT OUTER JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) WHERE comment_approved = '1' AND comment_type = '' AND post_password = '' ORDER BY comment_date_gmt DESC LIMIT 50"; $comments = $wpdb->get_results($sql); $output = $pre_HTML; foreach ($comments as $comment) { ?> <li class="commentField"> <a href="<?php echo get_permalink($comment->ID); ?>#comment-<?php echo $comment->comment_ID; ?>" title="<?php echo $comment->post_title; ?>"><?php $email = $comment->comment_author_email; echo get_avatar( $comment, 40 ); ?> </a> <span class="comAuthor"><?php echo strip_tags($comment->comment_author); ?><?php single_month_title('prefix', display) ?> </span><?php echo strip_tags($comment->com_excerpt)."…"; ?></span> <a class="commentLink" href="<?php comment_link(); ?>">Читать полностью</a> <div class="infiField"> <span class="dateGmt">Отзыв оставлен: <?php echo strip_tags($comment->comment_date_gmt); ?> <span class="authorEmail"><?php echo strip_tags($comment->comment_author_email); ?></span> <span class="authorUrl"><?php echo strip_tags($comment->comment_author_url); ?> </span> </div> </li> <?php } ?>Если не поможете, то все равно спасибо, много интересного нашел на вашем блоге.
Не подскажу. Придется заново код писать. И здесь немного по-другому получится.
Ок, все равно, спасибо
А ссылки на страницы можно закрыть noindex и nofollow
Хороший плагин, но надо его исключать в роботс.тхт а-то на выходе в поисковике это выглядит поршивенько.
что там исключать то?
Добрый день,
Может ли коды постраничной навигации корректно работать имея в адресной строке посторонние GET параметры?
Ищу альтернативные варианты постраничной навигации так как есть проблема описанная по этой ссылке.
Спасибо.
Вообще должна работать, если только параметры не конфликтуют!
Вот правило перезаписи:
[category/(.+?)/page/?([0-9]{1,})/?$] => index.php?category_name=$matches[1]&paged=$matches[2]
т.е. в чистом виде ссылка выглдит так: /index.php?category_name=name&paged=12
а передаваемые параметры по идее приписываются к ней.
попробуйте ЧПУ вырубить и проверить, тада все станет немного яснее.
Спасибо за ответ, ошибка была в запросе query_posts нужно было добавить
'paged' => get_query_var('paged')поэтому не получал номер страницы
да - постраничная навигация это хорошо, но что-то я не могу понять как ее прикрепить.
у меня на страницу записи выводятся из определенной категории..
<?php $postslist = get_posts('numberposts=-1&orderby=data&order=DESC&category=3'); ?> <?php foreach ($postslist as $post) : setup_postdata($post); ?> ... <?php endforeach; ?>и как к этому циклу прикрепить навигацию, не могу понять..(
если вдруг эта альтернатива совместима с таким выводом, буду очень благодарна..
Из вашего текста, простите, непонятно все-таки: грузит все-таки или нет, лишними запросами к БД плагин или нет??!!
Что значит:
???
Нет, не грузит.
Привет, Тимур. Случайно попал на Ваш блог, очень понравился. Сейчас некоторые Ваши фишки применяю на своем блоге. Ставил у себя навигацию по Вашей идее, но потом нашел более простое решение.
В знак благодарности оставил ссылочку на Вашу статью вот здесь.
Я делаю на всех своих сайтах вывод страниц полностью, т.е. без всяких "шагов", "Далее" и т.п., по-этому на некоторых сайтах очень много страниц, и они даже выходят за пределы экрана, т.е. идут в 1 строку, а как сделать, чтобы количество страниц разбивалось например, на N-количество страниц, дальше идет перенос строки, и следующая строка навигации? Или как то сделать, чтобы навигация не выходила за пределы страницы темы?