В стандартном функционале WordPress нет готового инструмента для автоматического создания связанных записей на основе тегов. Обычно для подобных задач используются плагины, например, YARPP (Yet Another Related Posts Plugin), но иногда хочется сделать кастомное решение, которое полностью контролируется и адаптируется под конкретные задачи.
Почему стоит создавать автоматические связи по тегам
Связанные записи увеличивают время нахождения пользователя на сайте, помогают улучшить внутреннюю перелинковку и SEO, а также повышают удобство навигации. Теги — один из самых простых и логичных способов связать контент, ведь они отражают ключевые темы записей.
Автоматизация такого процесса снижает ручной труд и исключает ошибки. К тому же кастомный код можно адаптировать так, чтобы выводились записи с нужными параметрами — например, только из определённых категорий или определённого типа постов.
Создаем функцию для выборки связанных записей по тегам
Для начала создадим функцию yarppru_get_related_posts_by_tags(), которая будет принимать ID текущей записи и возвращать массив объектов связанных записей, у которых есть пересечения по тегам.
function yarppru_get_related_posts_by_tags($post_id, $number = 5) {
$tags = wp_get_post_tags($post_id);
if (empty($tags)) {
return [];
}
$tag_ids = array_map(function($tag) { return $tag->term_id; }, $tags);
$args = [
'post_type' => 'post',
'posts_per_page' => $number,
'post__not_in' => [$post_id],
'tax_query' => [
[
'taxonomy' => 'post_tag',
'field' => 'term_id',
'terms' => $tag_ids,
'operator' => 'IN',
],
],
'orderby' => 'date',
'order' => 'DESC',
'no_found_rows' => true,
'ignore_sticky_posts' => true,
];
$query = new WP_Query($args);
return $query->posts;
}
Эта функция получает теги текущего поста, формирует запрос для выборки других постов с совпадающими тегами, исключая сам текущий пост.
Пояснения по параметрам WP_Query
post__not_in— исключаем текущий пост из результатов.tax_query— фильтр по таксономии тегов.no_found_rows— ускоряет запрос, так как не нужен подсчет общего количества.ignore_sticky_posts— чтобы липкие записи не влияли на результат.
Вывод связанных записей на странице записи
Теперь создадим функцию, которая выведет блок связанных записей в шаблоне single.php или через хук:
function yarppru_display_related_by_tags() {
if (!is_single()) {
return;
}
global $post;
$related_posts = yarppru_get_related_posts_by_tags($post->ID, 5);
if (empty($related_posts)) {
echo '<p>Связанные записи не найдены.</p>';
return;
}
echo '<div class="yarppru-related-posts"><h3>Связанные записи по тегам</h3><ul>';
foreach ($related_posts as $related) {
$title = esc_html(get_the_title($related));
$permalink = esc_url(get_permalink($related));
echo "<li><a href=\"$permalink\">$title</a></li>";
}
echo '</ul></div>';
}
Добавьте вызов yarppru_display_related_by_tags() в нужное место шаблона single.php, например сразу после контента записи.
Дополнительная фильтрация и улучшения
Если нужно, чтобы связи формировались не просто по любым совпадающим тегам, а с учетом веса, можно усложнить логику. Например, подсчитывать количество общих тегов и сортировать записи по убыванию количества совпадений.
Пример расширенного запроса с подсчетом совпадений:
function yarppru_get_related_posts_weighted($post_id, $number = 5) {
global $wpdb;
$tags = wp_get_post_tags($post_id);
if (empty($tags)) {
return [];
}
$tag_ids = implode(',', wp_list_pluck($tags, 'term_id'));
$sql = $wpdb->prepare(
"SELECT p.ID, COUNT(t.term_taxonomy_id) AS tag_match_count
FROM {$wpdb->posts} p
INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->term_taxonomy} t ON tr.term_taxonomy_id = t.term_taxonomy_id
WHERE t.term_id IN ($tag_ids)
AND p.ID != %d
AND p.post_type = 'post'
AND p.post_status = 'publish'
GROUP BY p.ID
ORDER BY tag_match_count DESC, p.post_date DESC
LIMIT %d",
$post_id, $number
);
$post_ids = $wpdb->get_col($sql);
if (empty($post_ids)) {
return [];
}
$query = new WP_Query([
'post__in' => $post_ids,
'orderby' => 'post__in',
'posts_per_page' => $number
]);
return $query->posts;
}
Такой подход позволит выводить наиболее релевантные записи с наибольшим количеством общих тегов.
Использование плагинов для автоматических связей по тегам
Если вы не хотите писать код, можете использовать плагины, которые умеют формировать связанные записи по тегам или таксономиям. Помимо YARPP, обратите внимание на:
- Contextual Related Posts — плагин с широкими возможностями настройки вывода связанных постов.
- Related Posts Thumbnails — удобный плагин с миниатюрами и фильтрами по тегам.
Но кастомный код всегда открывает больше возможностей для интеграции и оптимизации.
Оптимизация производительности при больших объемах данных
При большом количестве записей и тегов запросы могут замедляться. Чтобы этого избежать, рекомендуем:
- Кэшировать результаты функций через Transients API или сторонние кэш-плагины.
- Использовать индексы в базе данных для таксономий.
- Ограничивать количество выводимых связанных записей.
- При необходимости использовать AJAX-подгрузку связанного контента после загрузки страницы.
Пример простого кэширования результатов по тегам:
function yarppru_get_related_posts_by_tags_cached($post_id, $number = 5) {
$cache_key = 'yarppru_related_' . $post_id;
$cached = get_transient($cache_key);
if ($cached !== false) {
return $cached;
}
$related = yarppru_get_related_posts_by_tags($post_id, $number);
set_transient($cache_key, $related, HOUR_IN_SECONDS);
return $related;
}