Предыдущие записи из категории без плагина

09.06.2014

Отличное решение для внутренней перелинковки своих статей – это добавление блока “Рекомендуемые статьи” в конце записи. Есть различные плагины и скрипты, но проблема большинства из них в логике, многие плагины выводят рекомендуемые статьи по тегам или фразам из заголовков и текста. Этот вариант не очень удобен, потому что какие-то записи могут получить много ссылок и выводиться часто, а некоторые могут вообще не отображаться в блоке “Рекомендуем” и соответственно не получат никакого веса.

Самое отличное решение нашел на сайте Dimox’a – скрипт позволяет выводить предыдущие записи из категории, при чем зацикливает их по кругу, и получится, что последняя запись из категории в блоке “Рекомендуем” будет выводить первые записи, то есть вес внутри категории по записям распределится равномерно.

Код добавляем в single.php:

<?php
function show_previous_posts_from_category($the_post_id, $the_category_id = 0, $post_num)
{

  $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);
  global $post;
?>

  <h2><?php _e('Recent posts from category', 'creative'); ?> <?php the_category(', ') ?></h2>
  <ul class="recent-posts">
    <?php
    foreach ($result as $post) {
      setup_postdata($post);
    ?>

      <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>

      <?php
      $num++;
      $save_ids[] = $post->ID;
    }

    if ($num < $post_num || !$result) {
      $need_more = $post_num - $num;
      $save_ids[] = $the_post_id;
      $save_ids = join(',', $save_ids);
      $more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");

      foreach ($more_posts as $post) {
        setup_postdata($post);
      ?>

        <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>

    <?php
      }
    }
    ?>
  </ul>
<?php } ?>

<?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);
wp_reset_query();
?>

Так же есть вариант для вывода предыдущих записей с миниатюрой и цитатой:

<?php
function show_previous_posts_from_category($the_post_id, $the_category_id = 0, $post_num)
{
  function new_excerpt_length($length)
  {
    return 10;
  }
  add_filter('excerpt_length', 'new_excerpt_length');

  $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);
  global $post;
?>

  <h2><?php _e('Recent posts from category', 'creative'); ?> <?php the_category(', ') ?></h2>
  <ul class="recent-posts">
    <?php
    foreach ($result as $post) {
      setup_postdata($post);
    ?>

      <li>
        <?php the_post_thumbnail(array(40, 40)); ?>
        <a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a>
        <?php the_excerpt(); ?>
      </li>

      <?php
      $num++;
      $save_ids[] = $post->ID;
    }

    if ($num < $post_num || !$result) {
      $need_more = $post_num - $num;
      $save_ids[] = $the_post_id;
      $save_ids = join(',', $save_ids);
      $more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
      
      foreach ($more_posts as $post) {
        setup_postdata($post);
      ?>

        <li>
          <?php the_post_thumbnail(array(40, 40)); ?>
          <a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a>
          <?php the_excerpt(); ?>
        </li>

    <?php
      }
    }
    ?>
  </ul>

<?php } ?>

<?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);
wp_reset_query();
?>
 

Параметры выводятся в двух местах, их значения:

  • return 25; – это кол-во слов в кратком описании,
  • array(80,80) – размеры миниатюр, изменять в двух местах,
  • ($post->ID, $the_cat_id, 5); – количество предыдущих постов (5).

Рекомендую к прочтению:

Комментарии (2) к “Предыдущие записи из категории без плагина”

  • Дмитрий

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

    Ответить
    • Denis Creative

      Я так понимаю, что Вы уже нашли решение проблемы.
      Дмитрий:
      “Решил проблему исключением из запроса индексов для таблицы wp_posts
      заменил строку:
      FROM $wpdb->posts wposts
      на
      FROM $wpdb->posts wposts IGNORE INDEX (PRIMARY,type_status_id_date)
      костыль конечно, но помог, снизил время выполнения запроса с 5 секунд до 0.5
      актуально для сайтов с большим количеством постов, у моего в проблемной рубрике уже более 70000 постов, отсюда такая нагрузка.”

      Ответить

Оставить комментарий