Как отобразить похожие записи из той же категории?

2 окт. 2011 г., 17:08:14
Просмотры: 55.2K
Голосов: 17

Возможно ли отобразить похожие записи из той же категории, что и текущая запись?

0
Все ответы на вопрос 4
4
32

Один из вариантов:

$related = get_posts( 
    array( 
        'category__in' => wp_get_post_categories( $post->ID ), 
        'numberposts'  => 5, 
        'post__not_in' => array( $post->ID ) 
    ) 
);

if( $related ) { 
    foreach( $related as $post ) {
        setup_postdata($post);
        /*здесь может быть любой вывод поста*/
    }
    wp_reset_postdata();
}

Ссылки на документацию:

Переписанный вариант с использованием WP_Query():

$related = new WP_Query(
    array(
        'category__in'   => wp_get_post_categories( $post->ID ),
        'posts_per_page' => 5,
        'post__not_in'   => array( $post->ID )
    )
);

if( $related->have_posts() ) { 
    while( $related->have_posts() ) { 
        $related->the_post(); 
        /*здесь может быть любой вывод поста*/
    }
    wp_reset_postdata();
}
2 окт. 2011 г. 18:07:14
Комментарии

Будьте очень осторожны с именами переменных! Вы используете глобальную переменную $post для выполнения запроса, затем переопределяете $post в том же контексте внутри вашего цикла foreach.

EAMann EAMann
2 окт. 2011 г. 19:15:21

@EAMann - в целом вы правы, но по моему опыту использование setup_postdata() с чем-либо кроме $post не дает правильного вывода для функций типа the_title(). Теоретически wp_reset_postdata() должна сбрасывать $post обратно.

Michael Michael
2 окт. 2011 г. 20:08:25

Это потому что сама функция setup_postdata() ссылается на глобальную переменную $post. Вместо использования get_posts() вам следует создать кастомный экземпляр WP_Query и использовать его для получения записей. Это автоматически настроит данные записи и заставит the_title() и другие функции работать как положено.

EAMann EAMann
3 окт. 2011 г. 04:12:12

@EAMann Это довольно старый пост, но было бы здорово, если бы вы могли написать ответ о том, как правильно это сделать с пользовательским запросом и всем остальным

GiantCowFilms GiantCowFilms
25 нояб. 2015 г. 17:47:47
1

Еще один чистый и очень гибкий вариант:

Поместите этот код в файл functions.php

function example_cats_related_post() {

    $post_id = get_the_ID();
    $cat_ids = array();
    $categories = get_the_category( $post_id );

    if(!empty($categories) && is_wp_error($categories)):
        foreach ($categories as $category):
            array_push($cat_ids, $category->term_id);
        endforeach;
    endif;

    $current_post_type = get_post_type($post_id);
    $query_args = array( 

        'category__in'   => $cat_ids,
        'post_type'      => $current_post_type,
        'post__not_in'    => array($post_id),
        'posts_per_page'  => '3'


     );

    $related_cats_post = new WP_Query( $query_args );

    if($related_cats_post->have_posts()):
         while($related_cats_post->have_posts()): $related_cats_post->the_post(); ?>
            <ul>
                <li>
                    <a href="<?php the_permalink(); ?>">
                        <?php the_title(); ?>
                    </a>
                    <?php the_content(); ?>
                </li>
            </ul>
        <?php endwhile;

        // Восстановление оригинальных данных поста
        wp_reset_postdata();
     endif;

}

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

<?php example_cats_related_post() ?>

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

*Примечание - вам нужно изменить: post_not_in на post__not_in в вашем запросе

2 июл. 2018 г. 14:58:51
Комментарии

Отображается только одна запись. Можно ли вывести все записи из той же категории на странице категории?

Rahul Rahul
29 авг. 2019 г. 09:08:15
0

Вы можете использовать этот код для получения связанных записей из той же категории

$args = array(
                'category__in' => wp_get_post_categories( get_queried_object_id() ),
                'posts_per_page' => 5,
                'orderby'       => 'rand',
                'post__not_in' => array( get_queried_object_id() )
                );
    $the_query = new WP_Query( $args );

    if ( $the_query->have_posts() ) : ?>

        <ul class="">
        <!-- цикл -->
        <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

            <li>
                <h6>
                    <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
                    <?php the_title(); ?>
                    </a>
                </h6>
            </li>

        <?php endwhile; ?>
        <!-- конец цикла -->
        </ul>

        <?php wp_reset_postdata(); ?>

     <?php endif; ?>

и используйте этот код для получения связанных записей с теми же метками

$tags = wp_get_post_terms( get_queried_object_id(), 'post_tag', ['fields' => 'ids'] );
    $args = [
        'post__not_in'        => array( get_queried_object_id() ),
        'posts_per_page'      => 5,
        'orderby'             => 'rand',
        'tax_query' => [
            [
                'taxonomy' => 'post_tag',
                'terms'    => $tags
            ]
        ]
    ];
    $the_query = new WP_Query( $args );
    if ( $the_query->have_posts() ) : ?>

        <ul class="">
        <!-- цикл -->
        <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>

            <li>
                <h6>
                    <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">
                    <?php the_title(); ?>
                    </a>
                </h6>
            </li>

        <?php endwhile; ?>
        <!-- конец цикла -->
        </ul>

        <?php wp_reset_postdata(); ?>

    <?php endif; ?>
2 дек. 2019 г. 18:05:36
0

Этот ответ гарантирует, что связанные записи сортируются по количеству совпадающих тегов.

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

/**
 * Выбор записей с общими тегами.
 * Сортировка так, чтобы записи с несколькими совпадающими тегами были вверху.
 * Вторичная сортировка по самым свежим записям.
 *
 * @param $post_id
 * @param int $limit
 * @return array
 */
function related_posts($post_id, $limit = 5) {

    global $wpdb;

    $query  = "SELECT TOP %d x.object_id as ID
FROM (
SELECT TOP 10 tr1.object_id, COUNT(tr1.term_taxonomy_id) AS common_tag_count
FROM {$wpdb->term_relationships} AS tr1
INNER JOIN {$wpdb->term_relationships} AS tr2 ON tr1.term_taxonomy_id = tr2.term_taxonomy_id
WHERE tr2.object_id = %d
GROUP BY tr1.object_id
HAVING tr1.object_id != %d
ORDER BY COUNT(tr1.term_taxonomy_id) DESC
) x
INNER JOIN {$wpdb->posts} p ON p.ID = x.object_id
ORDER BY common_tag_count DESC, p.post_date DESC;";

    $query = $wpdb->prepare($query, $limit, $post_id, $post_id);
    $ids = $wpdb->get_col($query);
    $posts = [];
    foreach($ids as $id)  {
        $posts[] = get_post($id);
    }

    return $posts;

}

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

Обратите внимание, что этот запрос написан для SQL Server, поэтому некоторый синтаксис может потребовать обновления (например, TOP вместо LIMIT).

20 авг. 2018 г. 17:59:38