Вывод соседних записей рубрики
Итак, заказчиком поставлена была следующая задача: выводить к каждой записи 4 её "соседей" - ближайшие записи, созданные раньше и позже пользователем. Типа это улучшит индексацию сайта, и создаст дополнительное удобство пользователям. Причём, записи по возможности надо выводить - 2 добавленные ранее, и две добавленные после, чтоб название текущей оказалось в середине. Ну что просили, то мы и сделали
<?php
function neighbor_posts($post_id) {
global $wpdb;
// Нам нужна категория поста. Если у поста несколько категорий, будет взята первая
// Решение делалось под конкретное задание, посему универсальностью не обладает
$category = get_the_category($post_id);
$cat_id = $category[0]->cat_ID;
// Узнаём сколько записей добавлено до
$all_left_num = $wpdb->get_var("select count($wpdb->posts.ID) from $wpdb->posts join $wpdb->term_relationships on " .
"($wpdb->term_relationships.object_id = $wpdb->posts.ID) where ($wpdb->posts.ID < $post_id) " .
"and ($wpdb->term_relationships.term_taxonomy_id = $cat_id) and ($wpdb->posts.post_status='publish')");
// А сколько после
$all_right_num = $wpdb->get_var("select count($wpdb->posts.ID) from $wpdb->posts join $wpdb->term_relationships on " .
"($wpdb->term_relationships.object_id = $wpdb->posts.ID) where ($wpdb->posts.ID > $post_id) " .
"and ($wpdb->term_relationships.term_taxonomy_id = $cat_id) and($wpdb->posts.post_status='publish')");
$num_left = $num_right = 2; // Нам нужно по две записи с каждой стороны от нашей
// Но всего должно получиться 5 (вместе с текущей), поэтому
if ($all_left_num < 2) // Если слева нет 2 записей, компенсируем правыми
$num_right += (2 - $all_left_num);
if ($all_right_num < 2) // Если справа нет записей, компенсируем левыми
$num_left += (2 - $all_right_num);
// Теперь можно запросить сами записи. Для левых (предыдущих) задаём сортировку по ID по убыванию
// Таким образом гарантируем, что это будут именно ближайшие записи
$left = $wpdb->get_results("select $wpdb->posts.* from $wpdb->posts join $wpdb->term_relationships on " .
"($wpdb->term_relationships.object_id = $wpdb->posts.ID) where ($wpdb->posts.ID < $post_id) " .
"and ($wpdb->term_relationships.term_taxonomy_id = $cat_id) and ($wpdb->posts.post_status='publish') " .
"order by $wpdb->posts.ID desc limit $num_left");
// Для правых сортировку можно было не задавать, но так, по образу и подобию
$right = $wpdb->get_results("select $wpdb->posts.* from $wpdb->posts join $wpdb->term_relationships on " .
"($wpdb->term_relationships.object_id = $wpdb->posts.ID) where ($wpdb->posts.ID > $post_id) " .
"and ($wpdb->term_relationships.term_taxonomy_id = $cat_id) and($wpdb->posts.post_status='publish') " .
"order by $wpdb->posts.ID asc limit $num_right");
// здесь будут все посты, заголовки которых нам надо отобразить
$posts = array ();
// Левые отсортированы по убыванию, поэтому добавляем каждый следующий в начало $posts
// Таким образом в $posts они будут отсортированы по возрастанию
foreach ($left as $post)
array_unshift($posts, $post);
$posts[] = get_post($post_id);
foreach ($right as $post)
$posts[] = $post;
// Выводим ссылки на всю эту фигню
echo "<ul class='neighbor'>";
foreach ($posts as $post) {
echo "<li>";
if ($post->ID != $post_id)
echo sprintf("<a href='%s'>%s</a>", get_permalink($post->ID), $post->post_title);
else
echo $post->post_title;
echo "</li>";
}
echo "</ul>";
}
Важное замечание
От нескольких читателей блога поступил вопрос, что код "не работает". Для тех, кто не знает, объясняю: код функции следует поместить в файл functions.php темы, а из шаблона поста single.php вызывать, передав ID текущего поста!
Ваш комментарий
Комментарии