Отличный способ внутренней перелинковки статей (для WordPress)

Отличный способ внутренней перелинковки статей (для WordPress)

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

Комментарии (156)

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

  2. Можете глянуть как я использовал ваш скрипт, на любой из записей на моем сайте, который под именем…

  3. мне кажется для такого дела есть специальный плагин для вордпресс

  4. хороший урок для меня)) буду пробовать обязательно!

  5. Как, считаете, нужно ли в случае включения этого плагина отключать перелинковку типа кольцо в постах, которая присутствует во многих шаблонах WordPress.

    Вот, теперь наткнулся на этот пост и окончательно запутался в плагинах перелинковки.

    Раньше использовал Simple tags для этого (но там какая-то топорная перелинковка получается)
    Потом нашел в сети отличный плагин Yet Another Related Posts Plugin. Он сам анализирует страницы на ключевики, и выдает весьма релевантные страницы в похожих статьях.

    Вот теперь и ваш плагин, тоже походу отличная вещь, на чем же остановиться…

    • Если сравнивать мой код именно с плагинами похожих постов, то мой вариант однозначно лучше, т.к. у меня в перелинковку попадают ВСЕ статьи, а в «похожие» некоторые ссылки могут вообще не попадать, соответственно, перелинковываются не все статьи.

  6. Хоть и не пользуюсь Вордпресс, все равно спасибо. Понравилась идея сама по себе. Потому как, для вывода низкочастотников — милое дело внутрення перелинковка. А ваш способ отлично позволяет это дело автоматизировать. Надо бы сообщество «моего» движка попинать насчет такого плагина.))

  7. Если у кого выводятся последние записи вместо предыдущих попробуйте изменить
    if ($postDate2 ID != $postID) {
    на
    if ($postDate2 && $postDate2 ID != $postID) {

  8. Нашел баг: если 2 поста опубликованы в один день, то перелинковка работает неправильно, и в первом и во втором варианте (который прислал Штудер) написания кода. Только в первом варианте, одна из статей (та которая раньше опубликована) линкуется во всех предыдущих постах, а во втором варианте она игнорируется, т.е не линкуется вообще.

    Думаю если добавить в код проверку по времени это должно помочь. Вот только не силен в php, сам исправит не смогу.

    • Тьфу, блин.
      А я то сразу не сообразил почему у некоторых постов дата пустая.
      Вот теперь когда проблема понятна можно будет ее и решить :)

      Вечером или завтра выложу код как поправить.

    • Вопрос решается следующим образом. В коде нужно заменить в двух местах Y-m-d на Y-m-d-H. Только при этом не нужно делать замену, о которой писал Штудер, иначе работать не будет.

  9. А может стоить выложить ПОЛНОСТЬЮ правленый код, а то мне вот ну никак не хочется ставить не работающий код, а потом искать, как его поправить? Просто сделать ссылку на архив с последней версией кода и думаю, это будет хорошо. :)

    • Внес поправку. Попробуйте.

      • Спасибо, заработало.
        Вот только хотела уточнить, а этот код берёт только одну запись в день?
        Я просто думала, что он выводить действительно последние записи…
        А он у меня выводит по одной записи за пять предыдущих дней…
        одну за 10,10; одну за 9,10; одну за 8,10 и т.д. а то что в день может быть более чем одна запись, игнорируется.
        Так и было задумано?

        • нет не было так задумано, он должен действительно выводить Предыдущие записи.

          Dimox, замена на Y-m-d-H не дала никакого результата (хотя должна была по идее). Как я писал раньше при вашем условии (if ($postDate2 ….), если 2 статьи имеют одну дату, то более ранняя статья линкуется во всех предыдущих статьях, в случае Штудера — наоборот игнорируется

        • Поскольку у меня не бывает по нескольку постов в день, я сделал проверку только по дням.

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

          Так что вам еще придется делать обратную замену этого изменения.

  10. Наткнулся на ряд занимательных моментов связанных с публикацией постов разных подкатегорий одной категории, а также в случае если пост относится к нескольким рубрикам (иногда без этого никак).

    Поправить не получается… ибо с температурой 38 с копейками и нехилым кашлем писать сложновато. Быстрее бы оклематься и доделать все нафиг. Мне кажется что значительно быстрее все будет работать если инфу по кольцевой перелинковке запихнуть в отдельную базу. А вы что думаете по этому поводу?

    • На счет БД не согласен, не вижу в этом смысла. Нужно стараться использовать ее как можно меньше. На моем хостинге, например, очень тормозное подключение к БД, благо, кэширование блога от этого спасает.

  11. Понятно (правда не совсем)
    Просто до начала изучения php я занимался программированием на java для корпоративных систем. Там проблема с базами не была такой острой. А привычка осталась…

  12. Все, я нашел решение возникших проблем, о которых писали в комментариях выше. Причина была в использовании функции the_date(). Поправки в статье сделал, обновите, пожалуйста, у себя код.

    Теперь должно работать правильно, даже если статьи публикуются каждую минуту =)

  13. суперское решение по перелинковке. спасибо за код

  14. Отлично, Dimox, теперь плугин работает как надо :)

    Моя дотошность меня доканает. Как ограничить сей код от другого в шаблоне, чтоб он не затрагивал другие функции.
    Сейчас поясню. Если сразу после кода поставить допустим , то будет отображаться не настоящий заголовок, а заголовок наобум, ну или стандартная вордпрессовская перелинковка постов в кольцо тоже перестает правильно работать.

    Ставил на несколько сайтов, и что примечательно на одном сайте этих симптомов не было. Шаблоны везде разные.

    Просьба сильно не пинать ;-)

  15. Да, очень интересный способ перелинковки. Нужно тоже попробовать.
    А я пользовался и сейчас пользуюсь плагином Text-replacement, он тоже неплохой.
    Простая замена слов и фраз, которые прописываешь на ссылки к нужным записям или категориям, причем количество неограниченно.

  16. Сразу выражу огромную благодарность Dimox’у за то, что он есть :)

    Хочу обратить внимание на сам принцип этого варианта реализации идеи перелинковки. Меня он очень смущает, а именно вот эта начальная выборка:
    query_posts(‘showposts=10000&cat=’.$cat);

    Получается что выбираются все посты из категории, а уже потом проводятся операции по отсеиванию не нужных. Мне кажется так делать нельзя! Потому что, чтобы сгенерировать одну страницу пхп приходится загрузить тонну информации… А если в категории больше 1000 постов, нужно будет получить инфу всей тысячи? По-моему это негативно повлияет на скорость генерации страницы.

    Не лучше ли использовать такой принцип: Получить ИД поста, сделать мини запрос к БД который выберит предыдущие 5 ID постов (where post_id < ID ... limit 5) и вывести ссылки по полученым 5-ти ИД. При таком подходе получится что пхп обработает только то что нам необходимо. Ничего лишнего. Хотя может я чего-то не понимаю. Поэтому ничего не утверждаю :) В запросах к БД практически не разбираюсь, а то бы выложил свой вариант.

    • Я тоже не разбираюсь в запросах к БД, поэтому сделал так, как смог.

    • Совершенно случайно наткнулся сегодня в кодексе на реализацию вывода с использованием прямых запросов к БД и тут же вспомнилась эта статья :) В общем, прилично посидев получилось таки у меня реализовать, что писал до этого. Вот собственно и код, который можно вставить в functions.php или просто в конец файла, который отвечает за вывод записей (single.php):

      
      <?php 	
      
      function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num = 5){
      
      $num = 0;
      
      global $wpdb;
      
      $sql = "SELECT wposts.* 
      FROM $wpdb->posts wposts
      	LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
      	LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
      WHERE $wpdb->term_taxonomy.taxonomy = 'category'
      	AND $wpdb->term_taxonomy.term_id = '$the_category_id'
          AND wposts.post_status = 'publish'
          AND wposts.post_type = 'post'
      	AND wposts.ID < '$the_post_id'
      ORDER BY wposts.ID DESC
      LIMIT $post_num";
      
      $result = $wpdb->get_results($sql, OBJECT);
      
      //if (!$result){ echo "Записей не найдено"; return false; }
      
      global $post;
      
      echo '<ul>';
      foreach ($result as $post){ setup_postdata($post);
      //выводим информацию как обычно в ВП это бывает :)
      echo '<li><span>',the_time('j/m'),' </span><a href="'.get_permalink().'" rel="bookmark">'.get_the_title().'</a></li>';
      $num++;
      }
      
      
      // если предыдущих постов меньше заданого колличества, выводим ниже последние из рубрики
      if ( $num < $post_num || !$result ){ $need_more = $post_num-$num;
      $more_posts = get_posts("numberposts=$need_more&category=$the_category_id");
      foreach ($more_posts as $post){ setup_postdata($post);
      //выводим информацию как обычно в ВП это бывает :)
      echo '<li><span>',the_time('j/m'),' </span><a href="'.get_permalink().'" rel="bookmark">'.get_the_title().'</a></li>';
      }}
      
      echo '</ul>';
      }
      
      
      ?>	
      

      В том месте где необходимо вывести ссылки ставим

      
      <?php $the_cat = get_the_category(); $the_cat_id = $the_cat[0]->cat_ID;
      show_previous_posts_from_category( $post->ID, $the_cat_id, 5); ?>
      

      Где 5 — это колличество необходимых нам ссылок.

      Преимущества данного варианта над вариантом Dimox’a в том что из БД запрашивается только то количество информации которое необходимо. Да и тут в комментах видел кое-где конфликты кода возникали. Вроде с таким подходом конфликтов быть не должно, хотя время покажет :)

      Себе на сайт такую перелинковку ставить не собираюсь, потому что не для людей она! А для хорошей индексации роботами есть и другие способы, тот же sitemap.xls. Хотелось бы услышать веские аргументы в защиту такой перелинковки статей.

      • Спасибо за вариант. Обязательно протестирую, как появится свободное время.

        • Kama, все очень даже для людей. Мне, например, очень понравилось — удобно не залезаю в рубрику, просматривать предыдущие статьи на блоге.

          Dimox, спасибо за решение. Сравнил два варианта: предложенный тобой и Kama.

          При использовании твоего варианта возникла проблема: увеличение времени генерации поста (только поста) с 0.5 сек до почти 2.5 сек, а также увеличение потребления памяти почти на 4Mb (!). Заметил также, что и твои посты открываются долго. Проверял и на своем шаблоне и на дефолтном.

          Вариант Kama не показал ничего отрицательного.

          • Kama, все очень даже для людей. Мне, например, очень понравилось – удобно не залезаю в рубрику, просматривать предыдущие статьи на блоге.

            Чет я погоречился насчет «Не для людей» :) Согласен, что в некоторых случаях такой вывод очень даже удобен. Просто у меня для записей выводится последнее из рубрики, а сайт новосной…

            При использовании твоего варианта возникла проблема: увеличение времени генерации поста (только поста) с 0.5 сек до почти 2.5 сек

            Оно и правильно, ведь при использовании варианта Dimox’a, из БД вытаскиваются все существующие посты из данной категории, а это порой очень большой объем информации и громоский запрос к БД…

            Немного оффтопа. Дима (сорри за неофициальность) вставь в поля Имя и Е-mаil для комментариев в value $comment_author, $comment_author_email и $comment_author_url соответственно. Неудобно постоянно вводить Имя и Мыло :)
            Имею ввиду:


            <input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" />
            <input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" />
            <input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" />

            Насколько я понял эти параметры запоминаются ВП где-то в кукесах (или гдет еще) и однажды заполнив Имя, Мыло, ЮРЛ нет необходимости писать их снова при новом комменте.

      • Протестировал. Наблюдается следующая проблема — если в рубрике количество постов меньше, чем количество необходимых нам ссылок, то ссылки в списке дублируются.

        • Этот момент я не учел, хотя это не так страшно вроде — как только количество постов будет равно колличеству выводимых ссылок, то все нормализется, ну а решение этой проблемки такое:
          В первом цикле после $num++; добавляем $save_ids[] = $post->ID; (т.е. собираем ИД постов)

          ...
          $num++;
          $save_ids[] = $post->ID;
          }

          Во втором цикле после: $need_more = $post_num-$num; добавляем: $save_ids = join (‘,’, $save_ids); и в выборку постов добавляем: &exclude=$save_ids (т.е. исключаем полученые ранее ИД постов)

          if ( $num < $post_num || !$result ){ $need_more = $post_num-$num; $save_ids = join (',', $save_ids);
          $more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
          • Показывает ошибку:

            
            Warning: join() [function.join]: Bad arguments. в строке:
            
            if ( $num < $post_num || !$result ){ $need_more = $post_num-$num; $save_ids = join (',', $save_ids);
            

            и, соответственно, все еще неправильно показывает ссылки.

            • Нашел свой очередной недочет (сорри не протестировал, полностью перже чем выложить). В общем надо дабавить $save_ids[] = $the_post_id; перед $save_ids = join (’,’, $save_ids);

              if ( $num < $post_num || !$result ){  $need_more = $post_num-$num; $save_ids[] = $the_post_id; $save_ids = join (',', $save_ids);

              А то если перейти на первую запись в категории, то получается предыдущих ИД записей нет которые должны собираться в $save_ids и соответствено туда ничего не собирается, а функция join не принимает пустой массив, поэтому ошибка.

  17. Использовал эту идею с самого начала. Теперь попробовал вариант от Kama, стало ещё лучше!! Спасибо вам обоим =)

  18. Dimox, спасибо за код. Когда-то давно прочитал, но в закладки не занес, а теперь понадобилось. Хорошо, что быстро вспомнил, где именно видел :)

  19. Код уже рабочий в посте? или по комментариям собирать нужно? )))

  20. Поставил код перелинковки от Kama, после этого начались проблеммы с комментариями, после того как комментарий оставлен он попадает в другую запись… такое ощущения что какие то проблемы с переменной $post (такое ощущение что конфликтует форма комментариев и перелинковка). Потому что как только убираем код перелинковки, все отлично работает.

Ваш комментарий