Как вывести похожие записи без использования плагинов

Тема сама по себе не новая и в инете навалом всяких реализаций. Я вообще не хотел об этом писать — согласился лишь по просьбе одного из читателей моего блога.

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

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

Вывод похожих постов из тех же категорий и/или меток, что и текущий пост

Этот код поможет вам:

  • Вывести посты, которые находятся в тех же рубриках, что и текущий пост.
  • Вывести посты, которые отмечены теми же метками, что и текущий пост.
  • Всё вместе и сразу.

Кроме того, этот код будет работать для любых произвольных таксономий.

// необязательно, но в некоторых случаях без этого не обойтись
global $post;
 
// тут можно указать post_tag (подборка постов по схожим меткам) или даже массив array('category', 'post_tag') - подборка и по меткам и по категориям
$related_tax = 'category';
 
// получаем ID всех элементов (категорий, меток или таксономий), к которым принадлежит текущий пост
$cats_tags_or_taxes = wp_get_object_terms( $post->ID, $related_tax, array( 'fields' => 'ids' ) );
 
// массив параметров для WP_Query
$args = array(
	'posts_per_page' => 4, // сколько похожих постов нужно вывести,
	'tax_query' => array(
		array(
			'taxonomy' => $related_tax,
			'field' => 'id',
			'include_children' => false, // нужно ли включать посты дочерних рубрик
			'terms' => $cats_tags_or_taxes,
			'operator' => 'IN' // если пост принадлежит хотя бы одной рубрике текущего поста, он будет отображаться в похожих записях, укажите значение AND и тогда похожие посты будут только те, которые принадлежат каждой рубрике текущего поста
		)
	)
);
$misha_query = new WP_Query( $args );
 
// если посты, удовлетворяющие нашим условиям, найдены
if( $misha_query->have_posts() ) :
 
	// выводим заголовок блока похожих постов
	echo '<h3>Похожие посты</h3>';
 
	// запускаем цикл
	while( $misha_query->have_posts() ) : $misha_query->the_post();
		// в данном случае посты выводятся просто в виде ссылок
		echo '<a href="' . get_permalink( $misha_query->post->ID ) . '">' . $misha_query->post->post_title . '</a>';
	endwhile;
endif;
 
// не забудьте про эту функцию, её отсутствие может повлиять на другие циклы на странице
wp_reset_postdata();

Вручную устанавливаем в админке посты, которые хотим вывести

На мой взгляд это самый оптимальный способ вывода именно релевантных постов.

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

Выводить похожие записи мы будем в два шага.

Шаг 1. Произвольные поля

Как я уже сказал, нам нужно зайти на страницу редактирования поста и указать там посты, которые мы добавим в «Похожие записи».

Как это делается, показано на скриншоте:

Похожие посты в качестве значения произвольного поля.

А теперь подробнее:

  • В качестве названия произвольного поля можете использовать любое, которое ещё не было задействовано на вашем сайте (какие были задействованы, можно узнать, нажав на выпадающий список —Выбрать—). Как видно по скриншоту, я использовал my_related_posts.
  • Значением произвольного поля будет перечисление ID-ов похожих постов через запятую (без пробелов). Чтобы узнать ID поста, просто перейдите на его страницу редактирования и посмотрите на URL.
  • Если у вас нет такого блока с произвольными полями, в правом верхнем углу откройте вкладку «Настройки экрана» и напротив «Произвольные поля» поставьте галочку.
    Произвольные поля в настройках экрана
  • Вы также можете не использовать стандартный не очень удобный метабокс произвольных полей, а создать свой собственный (допустим с выпадающим списком названий постов, так как задавать их по ID не очень и удобно).

Шаг 2. Вывод релевантных постов

Итак, сразу код, вставляем туда, где хотим вывести похожие посты:

// проверяем, заданы ли похожие посты в админке
if( $my_related_post_ids = get_post_meta($post->ID, 'my_related_posts', true)) :
	$related_args = array(
		'posts_per_page' => -1, // сколько постов будет указано в админке, столько и выведется
		'post__in'=> explode(',', $my_related_post_ids), // в качестве значения нужно будет передать массив
		'orderby' => 'post__in' // посты будут сортироваться в том же порядке, в котором они перечислены в админке
	);
	$misha_query = new WP_Query( $related_args );
 
	// если посты, удовлетворяющие нашим условиям, найдены
	if( $misha_query->have_posts() ) :
 
		// выводим заголовок блока похожих постов
		echo '<h3>Похожие посты</h3>';
 
		// запускаем цикл
		while( $misha_query->have_posts() ) : $misha_query->the_post();
			// в данном случае посты выводятся просто в виде ссылок
			echo '<a href="' . get_permalink( $misha_query->post->ID ) . '">' . $misha_query->post->post_title . '</a>';
		endwhile;
	endif;
 
	// не забудьте про эту функцию, её отсутствие может повлиять на другие циклы на странице
	wp_reset_postdata();
endif;

Выводим похожие посты с изображениями-миниатюрами

Решил написать отдельную главу, которая будет посвящена именно оформлению блока с похожими постами.

Я буду рассчитывать, что у вас уже есть какие-нибудь базовые знания по миниатюрам записей, если нет, то можете почитать здесь.

Сразу покажу,что у нас в итоге должно получиться (я использовал стандартную тему WP Twenty Tvelve):

Похожие записи

Как это реализовать, по порядку:

  1. Используйте один из рассмотренных выше способов для вывода похожих постов.
  2. Для того, чтобы вывести изображение-превьюшку к посту, вы можете воспользоваться функцией the_post_thumbnail().
  3. Для того, чтобы записи шли красиво друг за другом в ряд, используйте стили CSS:
    /* .single_related - это блок одного поста */
    .single_related {
    	float: left;
    	width: 150px; /* задаем ширину */
    	margin-right:8px; /* отступ справа */
    }
    .single_related:nth-child(4){
    	margin-right:0; /* у последнего, четвертого элемента, отступа справа быть не должно */
    }

Если у вас возникнут какие-либо вопрсосы или появятся трудности, пожалуйста, оставьте комментарий. Буду рад вам помочь.

Подпишитесь, чтобы раз в неделю получать свежие статьи с блога по email.

Статьи, которые могут помочь вам с выводом блока похожих постов

Комментарии 20

  • Артем21 марта 2015 в 22:03 #

    Хорошая статья. Возник вопрос, а что делать если нужно выводить похожие статьи с картинками, но при этом миниатюры в статьях не используются?

    • Миша22 марта 2015 в 08:03 #

      Можно вытащить одно из изображений поста:

      $args = array(
      	'post_parent' => $post->ID, // ID поста
      	'post_type' => 'attachment', // тип изображений - аттачменты
      	'numberposts' => 1, // нам хватит и одного изображения
      	'post_mime_type' => 'image' // только изображения, т е приложенные к посту файлы другого типа не трогаем
      );
      if ( $images = get_children( $args ) ) { // если у поста есть изображения
      	echo wp_get_attachment_image( $images[0]->ID, 'thumbnail' );
      }

      Как-то так :)

  • Кирилл5 июля 2015 в 15:07 #

    Михаил, а как у тебя выводится список похожих постов?

  • Иван26 сентября 2015 в 17:09 #

    Отлично, то что искал!
    Только Ваш код выводит в похожих записях также и текущую запись, я исключил ее так, в аргументы добавил

    'post__not_in' => array($post->ID), //Не выводить текущую запись
  • Егор27 октября 2015 в 16:10 #

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

  • Егор27 октября 2015 в 17:10 #

    Только вот где ошибка? Не оборачивается картинка ссылкой. Я так вывел:

     echo '<a href="' . get_permalink( $misha_query->post->ID ) . '"> '. the_post_thumbnail() .'  ' . $misha_query->post->post_title .   '</a>';

    В исходном коде в данном случае картинка встает перед тегом

    <a>

    . Я ее же поставил внутрь тега.

    • Миша28 октября 2015 в 06:10 #
      echo '<a href="' . get_permalink( $misha_query->post->ID ) . '"> '. get_the_post_thumbnail() .'  ' . $misha_query->post->post_title .   '</a>';
  • Егор28 октября 2015 в 07:10 #

    Огромное спасибо, Михаил. Классный плагин похожих записей у вас вышел. И легкий. Самое главное, что можно наиболее релевантные статьи выводить. Сейчас поставлю ваш код. Я не ту функцию просто применил.

  • Егор28 октября 2015 в 09:10 #

    Я еще не надоел? Установил, теперь дело за малым, 150 постов отредактировать :) Как я понял, если не заполнено произвольное поле, то блок с похожими постами остается пустой.

  • Егор28 октября 2015 в 14:10 #

    Ну да, вроде, но у меня не выводится. Хотя в каждой рубрике далеко не по три поста. Все перепроверил, символ в символ код ставил, не идет. И на другом шаблоне, на стандартном Twenty Twelve не выводит автоматически из тех же рубрик.

  • Роберт3 ноября 2015 в 17:11 #

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

    • Миша4 ноября 2015 в 09:11 #

      Конечно, при помощи get_post_meta().

      • Роберт4 ноября 2015 в 10:11 #

        точно)

        оформил вывод

        echo '<a href=' . get_permalink( $misha_query->post->ID ) . '> <p><img src=' . get_post_meta($post->ID, 'preview', true) . '></p> <h3>' . $misha_query->post->post_title . '</h3></a> <p>' . get_post_meta($post->ID, '111', true) . '</p>';

        только как бы еще перед тем как выводить какое-либо произвольное поле проверять добавлено ли оно к записи, чтобы теги не выводить

  • Alex27 января 2016 в 20:01 #

    Спасибо за статью.
    Возник вопрос, а как сделать кнопку "показать еще", чтоб показывались похожие статьи, по умолчанию показывается 15, хочу чтоб пользователь нажимал кнопку и получал еще 15 шт.

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

phpjsHTMLCSSSQLПросто код
  Для того, чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или авторизуйтесь на сайте.
Получайте новости блога по email или следите за мной в социальных сетях.
  • Владимир: и на третьей строке не хватает скобки ) закрывающей if :)

  • Миша: Добрый вечер! Рекомендую получить ID пользователя через функцию get_current_user_id().

  • Дмитрий: Миша, подскажите пожалуйста, я использую такой редирект, но он не срабатывает: add_action( 'template_redirect', funct...

  • Миша: Ну как не определена - это аргумент функции. Или я просто вас не до конца понимаю.

  • Артем: Ага, понял. Вот только почему $args? Она же нигде не определена, по логике должна быть переменная $true_field_params или...