Привіт, хлопці. Сьогоднішній пост народився, можна сказати, не випадково. Не подумайте, що я раптом вирішив написати баян, який і так всі знають і, що не раз уже писалося на різних блогах. Зовсім ні, і приставка «Правильна» в назві поста дещо означає.

Все почалося з того, що деякі системи аналізу сайтів мені показували повні дублі деяких сторінок блогу (наприклад, http://alaev.info/blog і http://alaev.info/blog/, http://alaev.info/blog/category/seo і http://alaev.info/blog/category/seo/ та ін), притому, що цих сторінок я не міг знайти вупор, та й самі дублюючі адреси автоматично редиректились на правильні (правильні у мене це без слеша на кінці). Я не міг зрозуміти звідки це береться і де робот-аналізатор міг їх знаходити. Ночами перестав спокійно спати із-за цього…

Я почав дуже ретельно переглядати всі внутрішні посилання блогу, раптом я десь сам встановив такі посилання і не помітив. Але як ви вже, напевно, зрозуміли з заголовка поста, я знайшов проблему в посторінкової навігації мого WP.

Перша думка – кривий плагін WP-Pagenavi, не інакше. Пішов робити «розпил» файлів плагіна, там виявилося все не просто і дуже заплутано, але я розібрався з проблемою за півгодини. Але це не головне.

Я згадав, що колись чув, що можна зробити посторінкову навігацію для WordPress і без всяких плагінів – пішов шукати і тут же знайшов безліч варіантів. У мене була надія, що якщо робити все самому і вручну без плагінів, таких косяків бути не повинно. Виявилося інакше – деякі «самопали» на ділі виявилися ще гірше, і замість того щоб показувати посилання на основну сторінку і без слеша, як мені треба, вони показували /page/1, що є повним дублем основної сторінки, при цьому реально існуючим.

Щож, знову доведеться «пиляти» — мені не в першій. Для цього я вибрав саме адекватне із знайдених рішень (ось воно) за що велике спасибі блогу wp-kama.ru. До речі, проблема посторінкової навігації в цьому варіанті така ж як і в плагіні WP-Pagenavi – зайвий слеш для першої сторінки. Але є безперечний плюс – ми позбудемося плагіна!

Отже, кілька причин, по яких варто відмовитися від плагіну WP-Pagenavi на користь альтернативи, запропонованої в цьому пості:

  • За зручність налаштувань в адмін-панелі доводиться платити ціною зайвих запитів, так як ці налаштування зберігаються в БД, а потім від туди і беруться, хоча це в теорії, а на практиці вони беруться з кеша опцій WordPress, але тим не менш…
  • В продовження першого пункту – зручність у даному випадку річ сумнівна – посторінкова навігація, це така справа, що налаштував якось і забув. А замінити кілька значень в коді (в якому, до речі, є всі пояснення) не складе труднощів навіть новачкові.
  • Якщо ви просунутий користувач і не вперше чуєте слово «php», то при бажанні щось змінити (чи то зовнішній вигляд або щось ще) це не складе ніяких труднощів – код простий, зрозумілий та лаконічний.
  • При написанні коду, його автор kama використовував ті ж css-стилі, що і використовує плагін Pagenavi, так що вам навіть не доведеться заново все оформляти.
  • Ну і останній пункт, найважливіший, заради якого все і затівалося – будуть нормальні посилання на першу сторінку, не виникне ніяких дублів і зайвих редиректів.
  • Менше слів, більше діла – розглянемо код і що з ним робити.

    Відкриваємо в адмінці «Зовнішній вигляд -> Редактор» і вибираємо Функції теми functions.php). На початок цього файлу вставляємо наступний код:

    /*** Альтернатива 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_show1;
    $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.
    \n
    ;
    if ($text_num_page){
    $text_num_page = preg_replace (‘!{current}|{last}!’,‘%s’,$text_num_page);
    $out.= sprintf ($text_num_page,$paged,$max_page);
    }
    if ($start_page >= 2 && $pages_to_show < $max_page) {
    $out.= . ($first_page_text?$first_page_text:1) .;
    if($dotright_text && $start_page!=2) $out.= .$dotright_text.;
    }
    if ($backtext && $paged!=1) $out.=
    .$backtext.;
    for($i = $start_page; $i <= $end_page; $i++) {
    if($i == $paged) {
    $out.= .$i.;
    } else {
    $out.=
    .$i.;
    }
    }
    if ($nexttext && $paged!=$end_page) $out.=
    .$nexttext.;
    //з кроком посилання
    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.= .$dotright_text2.;
    $out.=
    .$i.;
    }
    }
    }
    if ($end_page < $max_page) {
    if($dotright_text && $end_page!=($max_page1)) $out.= .$dotright_text2.;
    $out.=
    . ($last_page_text?$last_page_text:$max_page) .;
    }
    $out.=
    .$after.\n;
    if ($echo) echo $out;
    else return $out;
    }

    /*** Альтернатива 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 $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.”
    \n”;
    if ($text_num_page){
    $text_num_page = preg_replace (‘!{current}|{last}!’,’%s’,$text_num_page);
    $out.= sprintf (“$text_num_page“,$paged,$max_page);
    }
    if ($start_page >= 2 && $pages_to_show < $max_page) {
    $out.= “. ($first_page_text?$first_page_text:1) .”;
    if($dotright_text && $start_page!=2) $out.= ‘‘.$dotright_text.’‘;
    }
    if ($backtext && $paged!=1) $out.= “.$backtext.”;
    for($i = $start_page; $i <= $end_page; $i++) {
    if($i == $paged) {
    $out.= ‘‘.$i.’‘;
    } else {
    $out.= “.$i.”;
    }
    }
    if ($nexttext && $paged!=$end_page) $out.= “.$nexttext.”;
    //з кроком посилання
    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.= ‘‘.$dotright_text2.’‘;
    $out.= “.$i.”;
    }
    }
    }
    if ($end_page < $max_page) {
    if($dotright_text && $end_page!=($max_page-1)) $out.= ‘‘.$dotright_text2.’‘;
    $out.= “. ($last_page_text?$last_page_text:$max_page) .”;
    }
    $out.= ”
    “.$after.”\n”;
    if ($echo) echo $out;
    else return $out;
    }

    Багато можуть не помітити, що саме мій варіант відрізняється від оригіналу, запропонованого kama. Пояснюю: змінено порядок виводу, тобто місцями поміняні деякі елементи, тепер стало більш юзабельно; і найголовніше – при формуванні деяких посилань я застосував php функцію string rtrim ( string $str [, string $charlist ] ), яка повертає рядок мені, але без слеша в кінці, якщо він є – що, власне, і потрібно було спочатку.

    Далі у всіх файлах шаблону, в яких потрібно додати навігацію, необхідно зручне місце вставити:

    if (function_exists(‘kama_pagenavi’)) kama_pagenavi(); ?>

    Якщо ви впевнені тим куди це треба вставляти, просто шукайте щось подібне:

    if(function_exists(‘wp_pagenavi’)) { wp_pagenavi(); } ?>

    І замінюйте на зазначену вище рядок.

    Ось і все готово, друзі!

    Тепер залишається відкрити файл /wp-content/plugins/wp-pagenavi/pagenavi-css.css скопіювати звідти весь код і вставити його в свій css файл (зазвичай це style.css і лежить в папці з вашою темою оформлення).

    Ну і останній крок – деактивуємо плагін WP-Pagenavi в адмінці і видаляємо повністю його папку з сервера 😉

    PS Заради цікавості перевірив перші прийшли в голову блоги – на всіх є така проблема, рішення якої я описав 🙂

    Удачі вам, друзі, і пам’ятайте – в SEO не буває дрібниць!

    Задавайте питання, коментуйте. До зв’язку.

    З повагою, Олександр Алаєв