Bài viết hướng dẫn tìm danh sách những bài viết (post) liên quan đến bài viết hiện tại theo các mục tiêu khác nhau.

Các hàm dưới đây sẽ trả về một array các post theo tiêu chí tìm kiếm đề ra. Sau khi có danh sách này, hãy hiển thị theo cách của bạn.

Danh sách bài viết gần đây

/**
 * $num_posts - Số lượng bài viết
 * $excluded_cats - Không lấy bài viết nằm trong DS category này
 * $orderby - Tiêu chí sắp xếp (mặc định là 'date' bài viết)
 * $order - Thứ tự sắp xếp (mặc định là DESC - từ lớn đến bé)
 */
function get_recent_posts($num_posts = 8, $excluded_cats = null, $orderby = 'date', $order = 'DESC') {
    $post_args = array(
            'orderby' => $orderby,
            'order' => $order,
            'post_type' => 'post',
            'posts_per_page'  => $num_posts,
            'ignore_sticky_posts' => 1,
            'category__not_in' => $excluded_cats
        );
    if (is_single())
        $post_args['post__not_in'] = array($post->ID);

    $query = new WP_Query( $post_args );
    $posts = $query->get_posts();
    wp_reset_query();

    return $posts;
}

Danh sách bài viết cùng chuyên mục (category) với bài viết hiện tại

/**
 * $num_posts - Số lượng bài viết
 * $excluded_cats - Không lấy bài viết nằm trong DS category này
 * $orderby - Tiêu chí sắp xếp (mặc định là 'date' bài viết)
 * $order - Thứ tự sắp xếp (mặc định là DESC - từ lớn đến bé)
 */
function get_related_posts_by_cat($num_posts = 8, $excluded_cats = null, $orderby = 'date', $order = 'DESC') {
    global $post;
    $cat_ID = array();

    // Tìm tất cả các category của post hiện tại
    $categories = get_the_category();
    foreach ($categories as $category):
        array_push($cat_ID, $category->cat_ID);
    endforeach;

    // Tìm các post có chứa ít nhất một trong những category trên
    $post_args = array(
            'orderby' => $orderby,
            'order' => $order,
            'post_type' => 'post',
            'posts_per_page'  => $num_posts,
            'ignore_sticky_posts' => 1,
            'category__in' => $cat_ID,
            'category__not_in' => $excluded_cats
    );

    if (is_single())
        $post_args['post__not_in'] = array($post->ID);

    $query = new WP_Query( $post_args );
    $posts = $query->get_posts();
    wp_reset_query();

    return $posts;
}

Danh sách bài viết cùng thẻ (tag) với bài viết hiện tại

/**
 * $num_posts - Số lượng bài viết
 * $excluded_cats - Không lấy bài viết nằm trong DS category này
 * $orderby - Tiêu chí sắp xếp (mặc định là 'date' bài viết)
 * $order - Thứ tự sắp xếp (mặc định là DESC - từ lớn đến bé)
 */
function get_related_posts_by_tag($num_posts = 8, $excluded_cats = null, $orderby = 'date', $order = 'DESC') {
    global $post;
    $markup = '';
    $tag_ID = array();

    // Tìm tất cả các tag của post hiện tại
    $tags = wp_get_post_tags($post->ID);
    if (count($tags) === 0)
        return;

    foreach ($tags as $tag) :
        array_push($tag_ID, $tag->term_id);
    endforeach;

    // Tìm các post có chứa ít nhất một trong những tag trên
    $post_args = array(
            'orderby' => $orderby,
            'order' => $order,
            'orderby' => 'rand',
            'post_type' => 'post',
            'posts_per_page'  => $num_posts,
            'ignore_sticky_posts' => 1,
            'category__not_in' => $excluded_cats,
            'tag__in' => $tag_ID
    );

    if (is_single())
        $post_args['post__not_in'] = array($post->ID);

    $query = new WP_Query( $post_args );
    $posts = $query->get_posts();
    wp_reset_query();

    return $posts;
}

Danh sách bài viết cùng tác giả với bài viết hiện tại

/**
 * $num_posts - Số lượng bài viết
 * $excluded_cats - Không lấy bài viết nằm trong DS category này
 * $orderby - Tiêu chí sắp xếp (mặc định là 'date' bài viết)
 * $order - Thứ tự sắp xếp (mặc định là DESC - từ lớn đến bé)
 */
function get_related_posts_by_author($num_posts = 8, $excluded_cats = null, $orderby = 'date', $order = 'DESC') {
    global $post;

    if ( is_author() ) :
        global $authordata;
        $post_args = array(
            'orderby' => $orderby,
            'order' => $order,
            'post_type' => 'post',
            'author' => $authordata->ID,
            'posts_per_page'  => $num_posts,
            'ignore_sticky_posts' => 1,
            'category__not_in' => $excluded_cats
        );
    elseif ( is_single() ) :
        global $post;
        $post_args = array(
            'orderby' => $orderby,
            'order' => $order,
            'post_type' => 'post',
            'author' => $post->post_author,
            'posts_per_page'  => $num_posts,
            'ignore_sticky_posts' => 1,
            'post__not_in' => array($post->ID),
            'category__not_in' => $excluded_cats
        );
    else :
        return array();
    endif;

    $query = new WP_Query( $post_args );
    $posts = $query->get_posts();
    wp_reset_query();

    return $posts;
}

Danh sách các bài viết liên quan tự chọn

Chức năng này cần cài thêm plugin Advanced Custom Fields. Với ACF, tôi tạo thêm một loạt trường bổ sung cho dạng bài viết (post) với field name có cú pháp related-post-ID, với ID bắt đầu từ 1.

Tham khảo cấu hình như hình dưới đây.

/**
 * $num_posts - Số lượng bài viết
 * @note Số lượng bài viết tối đa bằng số lượng custom field
 */
function get_related_posts_by_acf( $num_posts = 8 ) {
    global $post;
    $ret = array();
    
    if ( function_exists('get_field') ) :
        for ( $i = 1; $i <= $num_posts; $i++ ) :
            $post_obj = get_field( 'related-post-' . $i );
            $ret[$i] = $post_obj;
        endfor;
    endif;
    return $ret;
}