×

WordPress – выводим похожие записи без плагинов

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

Чем плох плагин WordPress Related Posts?

Это самый популярный плагин по данной тематике. И похожие записи он выводит без нареканий. Но у него есть огромные минусы.

Во-первых, чтобы вывести 5 ссылок под постом мы загружаем 123 файла, которые содержат больше двух мегабайт кода. Это многовато.

Количество файлов в папке WordPress Related Posts

Количество файлов в папке WordPress Related Posts

Во-вторых, этот плагин всегда вставляет похожие записи в конец текста записи и отделить основной текст от блока похожих статей не выйдет. Если вы будете просматривать страницу в режиме чтения, то ссылки никуда не денутся. Поисковики тоже не будут довольны, потому что в микроразметку записи у нас попадёт блок со ссылками.

В-третьих, при каждой загрузке страницы этот плагин отправляет данные на сайт zemanta, вставляя javascript код в заголовок страницы. Этот функционал не отключить настройками (но в коде можно закомментировать без последствий). Я понимаю, что таким образом они там учитывают статистику и прочее, но мой внутренний параноик негодует.

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

Чем заменить плагин?

Всё, что нам нужно, уже есть в WordPress. Для решения нашей задачи достаточно взять функцию wp_get_recent_posts и получить все записи в похожих категориях с пересекающимися тегами. WordPress Related Posts ориентируется на эти же параметры.

Похожие записи мы хотим видеть после текста записи в отдельном блоке, поэтому откорректируем шаблон одиночной записи single.php из нашей темы оформления.

Запись у нас выводиться функцией the_content() так что наш код будем вставлять после неё.

Вот сам код с подробнейшими комментариями:

<?php 
//получаем символьные идентификаторы тегов текущей записи,
//если они есть, и соберём их в строку через запятую
$arArticleTags = get_the_tags();
$tagStringForQuery = '';
if(!empty($arArticleTags)) {
  for($i = 0; $i < count($arArticleTags); $i++) {
    if($i != count($arArticleTags) - 1) {
      $tagStringForQuery .= $arArticleTags[$i]->slug . ',';
    }else{
      $tagStringForQuery .= $arArticleTags[$i]->slug;
    }
  }
}

//получаем числовые ID категорий текущей записи,
//если они есть, и соберём их в строку через запятую
$arArticleCategories = get_the_category($post->ID);
$categoriesStringForQuery = '';
if(!empty($arArticleCategories)) {
  for($i = 0; $i < count($arArticleCategories); $i++) {
    if($i != count($arArticleCategories) - 1 ) {
      $categoriesStringForQuery .= $arArticleCategories[$i]->cat_ID . ',';
    }else{
      $categoriesStringForQuery .= $arArticleCategories[$i]->cat_ID;
    }
    
  }
}

//инициализируем пустой массив записей
$arRelatedArticles = [];

//запрашивать похожие записи будем
//только если есть теги или категории
if(!empty($tagStringForQuery) or !empty($categoriesStringForQuery)) {
  //выбираем только 5 опубликованных записей,
  //не включая текущую и сортируем их по ID по убыванию
  $arArticlesFilter = [
    'post_type' => 'post',
    'post_status' => 'publish',
    'exclude' => $post->ID,
    'numberposts' => '5',
    'orderby' => 'ID',
    'order' => 'DESC',
    'cache_results' => true,
    'update_post_meta_cache' => true,
    'update_post_term_cache' => true
  ];
  
  //добавляем фильтр по тегам
  if(!empty($tagStringForQuery)){
    $arArticlesFilter['tag'] = $tagStringForQuery;
  }
  
  //добавляем фильтр по категориям
  if(!empty($categoriesStringForQuery)){
    $arArticlesFilter['category'] = $categoriesStringForQuery;
  }
  
  //запрашиваем записи и получаем ответ в виде массива
  $arRelatedArticles = wp_get_recent_posts($arArticlesFilter);
}

//если что-то получили, то выводим список
if(!empty($arRelatedArticles)){?>
    <nav class="article_related_links">
    <h3 class="related_post_title">Похожие записи</h3>
    
    <ul class="related_post wp_rp"><?
    foreach ($arRelatedArticles as $articleDetail){?>
      <li>
        <small class="wp_rp_publish_date">
		  <?=mysql2date('d M Y', $articleDetail['post_date'])?>
		</small>
        <a href="<?= get_permalink($articleDetail['ID']) ?>">
		  <?=$articleDetail['post_title'] ?>
		</a>
        <small class="wp_rp_comments_count">
		  (<?=$articleDetail['comment_count']?>)
		</small>
      </li>
    <?}?>
    </ul>
  </nav>
<?}?>

Можно конечно тоже взять и оформить всё это плагином, но тут не так много кода чтобы заморачиваться. Да и плагинофобия не позволяет =)

logo