WordPress. Плагин «Похожие записи»
25.05.2019
Теги: CMS • Web-разработка • WordPress • Плагин
Давайте создадим плагин, который для каждой записи будет выводить список похожих записей. Тут есть два варианта реализации:
- Вывести записи, которые находятся в тех же рубриках, что и текущая запись
- Вывести записи, которые отмечены теми же метками, что и текущая запись
Итак, создаем директорию tokmakov-related-posts
, а внутри нее — файл tokmakov-related-posts.php
. Привязываем к хуку the_content
анонимную функцию, в которой и будет весь наш код. Мы «подцепим» (конкатенация) к контенту записи html-код списка похожих постов.
<?php /* Plugin Name: Похожие записи Plugin URI: https://tokmakov.msk.ru Description: Выводит список записей, связанных с текущей записью Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ add_filter('the_content', function ($content) { });
Первый способ
С помощью WP_Query
получаем записи, которые находятся в тех же рубриках, что и текущая запись:
<?php /* Plugin Name: Похожие записи Plugin URI: https://tokmakov.msk.ru Description: Выводит список записей, связанных с текущей записью Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ add_filter('the_content', function ($content) { if (!is_single()) { return $content; } // получаем идентификатор текущей записи $id = get_the_ID(); // массив категорий, в которых расположена запись $categories = get_the_category($id); // массив идентификаторов категорий $ids = []; foreach ($categories as $category) { $ids[] = $category->cat_ID; } // получаем записи из этих категорий $query = new WP_Query([ // выбираем только пять записей 'posts_per_page' => 5, // из тех же категорий, что и текущая запись 'category__in' => $ids, // текущую запись исключаем из выборки 'post__not_in' => [$id], ]); // выводим полученные записи $related = ''; if ($query->have_posts()) { $related = '<h4>Похожие записи:</h4>' . PHP_EOL; $related .= '<ul>' . PHP_EOL; while ($query->have_posts()) { $query->the_post(); $title = get_the_title(); $link = get_the_permalink(); $related .= '<li><a href="' . $link . '">' . $title . '</a></li>' . PHP_EOL; } $related .= '</ul>' . PHP_EOL; wp_reset_postdata(); } return $content . $related; });
Второй способ
С помощью WP_Query
получаем записи, которые отмечены теми же метками, что и текущая запись:
<?php /* Plugin Name: Похожие записи Plugin URI: https://tokmakov.msk.ru Description: Выводит список записей, связанных с текущей записью Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ add_filter('the_content', function ($content) { if (!is_single()) { return $content; } // получаем идентификатор текущей записи $id = get_the_ID(); // массив тегов, с которыми связана запись $tags = wp_get_post_tags($id); // идентификаторы тегов, с которыми связана запись $ids = []; foreach ($tags as $tag) { $ids[] = $tag->term_id; } // получаем записи с такими же тегами $query = new WP_Query([ // выбираем только пять записей 'posts_per_page' => 5, // с теми же тегами, что у текущей записи 'tag__in' => $ids, // текущую запись исключаем из выборки 'post__not_in' => [$id], ]); // выводим полученные записи $related = ''; if ($query->have_posts()) { $related = '<h4>Похожие записи:</h4>' . PHP_EOL; $related .= '<ul>' . PHP_EOL; while ($query->have_posts()) { $query->the_post(); $title = get_the_title(); $link = get_the_permalink(); $related .= '<li><a href="' . $link . '">' . $title . '</a></li>' . PHP_EOL; } $related .= '</ul>' . PHP_EOL; wp_reset_postdata(); } return $content . $related; });
Эти два способа можно объединить — получить записи, которые находятся в тех же рубриках и которые отмечены теми же метками, что и текущая запись:
$query = new WP_Query([ // выбираем только пять записей 'posts_per_page' => 5, // из тех же категорий, что и текущая запись 'category__in' => $ctg_ids, // с теми же тегами, что у текущей записи 'tag__in' => $tag_ids, // текущую запись исключаем из выборки 'post__not_in' => [$id], ]);
Третий способ
При выборке записей с теми же метками есть существенный недостаток. В выборку могут попадать записи, у которых совпадает только одна метка. И при этом в выборку могут не попадать записи, у которых совпадают две или три метки. Условие построено так, что достаточно одного совпадения. Давайте это исправим — выбирать будем все записи, но отсортируем их по количеству совпадений меток. А потом покажем только первые пять:
<?php /* Plugin Name: Похожие записи Plugin URI: https://tokmakov.msk.ru Description: Выводит список записей, связанных с текущей записью Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ add_filter('the_content', function ($content) { if (!is_single()) { return $content; } // получаем идентификатор текущей записи $id = get_the_ID(); // массив тегов, с которыми связана запись $tags = wp_get_post_tags($id); /* * Для начала нам нужно получить все записи, связанные с * первым тегом, потом все записи, связанные со вторым * тегом и так далее. После этого узнать, у каких записей * больше совпадений по тегам с текущей записью. */ $posts = []; // сюда будем сохранять полученные записи $relevance = []; // сюда будем записывать кол-во совпадений foreach ($tags as $tag) { // получаем записи, связанные с текущим тегом $query = new WP_Query([ 'posts_per_page' => -1, 'tag__in' => [$tag->term_id], 'post__not_in' => [$id], ]); foreach ($query->posts as $value) { // сохраняем полученные записи if (!isset($posts[$value->ID])) { $posts[$value->ID] = $value; } // записываем кол-во совпадений if (isset($relevance[$value->ID])) { $relevance[$value->ID] = $relevance[$value->ID] + 1; } else { $relevance[$value->ID] = 1; } } } /* * Теперь все записи, связанные с тегами текущей записи у * нас в массиве $posts, а сколько раз та или иная запись * встретилась при выборках — в массиве $relevance. */ arsort($relevance); // нам нужно только пять самых релевантных записей $relevance = array_slice($relevance, 0, 5, true); $related = []; foreach ($relevance as $key => $value) { $related[] = $posts[$key]; } unset($posts, $relevance); /* * Выводим полученные записи */ $result = ''; if (!empty($related)) { $result = '<h4>Похожие записи:</h4>' . PHP_EOL; $result .= '<ul>' . PHP_EOL; foreach ($related as $post) { $title = get_the_title($post->ID); $link = get_the_permalink($post->ID); $result .= '<li><a href="' . $link . '">' . $title . '</a></li>' . PHP_EOL; } $result .= '</ul>' . PHP_EOL; } return $content . $result; });
- WordPress. Фильтр записей по произвольным полям. Часть 3 из 3
- WordPress. Фильтр записей по произвольным полям. Часть 2 из 3
- WordPress. Фильтр записей по произвольным полям. Часть 1 из 3
- WordPress. Добавляем мета-теги. Часть 3 из 3
- WordPress. Метабоксы. Часть 2 из 2
- WordPress. Произвольные типы записей
- WordPress. Пользовательские таксономии
Поиск: CMS • Web-разработка • WordPress • Плагин