Bài viết này mình chia sẻ đến bạn cách hiển thị bài viết liên quan theme GeneratePress mà không cần dùng plugin. Đây là một thủ thuật mà có lẽ blog dùng theme GeneratePress (bản miễn phí) nào cũng cần vì nó không được tích hợp sẵn. Bản trả phí thì mình chưa dùng nên không biết có hay không nữa ^^

Cách làm cũng rất đơn giản, bạn copy đoạn code bên dưới và chèn vào cuối file functions.php của theme/ child theme đang dùng là được. Nên chèn vào child theme sẽ tốt hơn, khi cập nhật sẽ không bị mất, còn nếu bạn không chèn vào child theme mà chèn trực tiếp thì nhớ lưu bài viết này lại, cập nhật theme thì copy dán vào lại là được.
//BÀI VIẾT LIÊN QUAN GENRATEPRESS BY HOCBAN.VN
add_action( 'generate_before_comments_container', 'gp_related_posts_php84_optimized' );
function gp_related_posts_php84_optimized(): void {
if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
return;
}
global $post;
if ( ! $post instanceof WP_Post ) {
return;
}
$current_id = $post->ID;
$cache_key = 'gp_rel_ids_' . $current_id;
$top4_ids = wp_cache_get( $cache_key, 'gp_related' );
if ( false === $top4_ids ) {
$current_cats = wp_get_post_categories( $current_id, [ 'fields' => 'ids' ] );
$current_tags = wp_get_post_tags( $current_id, [ 'fields' => 'ids' ] );
if ( empty( $current_cats ) && empty( $current_tags ) ) {
return;
}
$related = new WP_Query( [
'post__not_in' => [ $current_id ],
'posts_per_page' => 30,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'update_post_meta_cache' => false,
'fields' => 'ids',
'tax_query' => [
'relation' => 'OR',
[ 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $current_cats ],
[ 'taxonomy' => 'post_tag', 'field' => 'term_id', 'terms' => $current_tags ],
],
] );
if ( ! $related->have_posts() ) {
wp_reset_postdata();
return;
}
$scored_posts = [];
foreach ( $related->posts as $pid ) {
$post_cats = wp_get_post_categories( $pid, [ 'fields' => 'ids' ] ) ?: [];
$post_tags = wp_get_post_tags( $pid, [ 'fields' => 'ids' ] ) ?: [];
$common_cats = array_intersect( $current_cats, $post_cats );
$common_tags = array_intersect( $current_tags, $post_tags );
$score = ( count( $common_cats ) * 100 ) + ( count( $common_tags ) * 10 );
if ( $score > 0 ) {
$scored_posts[] = [ 'id' => $pid, 'score' => $score ];
}
}
wp_reset_postdata();
if ( empty( $scored_posts ) ) {
return;
}
usort( $scored_posts, fn( $a, $b ) => $b['score'] <=> $a['score'] );
$top4_ids = array_slice( array_column( $scored_posts, 'id' ), 0, 4 );
wp_cache_set( $cache_key, $top4_ids, 'gp_related', 6 * HOUR_IN_SECONDS );
}
if ( empty( $top4_ids ) ) {
return;
}
$top_posts = get_posts( [
'post__in' => $top4_ids,
'posts_per_page' => 4,
'post_status' => 'publish',
'orderby' => 'post__in',
'no_found_rows' => true,
'update_post_meta_cache' => false,
] );
if ( empty( $top_posts ) ) {
return;
}
//HIỂN THỊ với SEO Optimization
?>
<aside class="gp-related-posts" aria-labelledby="gp-related-title" itemscope itemtype="https://schema.org/ItemList">
<h3 id="gp-related-title" class="gp-related-title" itemprop="name">Bài viết liên quan</h3>
<ul class="gp-related-list">
<?php
$position = 1;
foreach ( $top_posts as $p ) :
setup_postdata( $p );
?>
<li class="gp-related-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<meta itemprop="position" content="<?php echo esc_attr( $position ); ?>">
<a href="<?php echo esc_url( get_permalink( $p ) ); ?>"
class="gp-related-link"
itemprop="url"
rel="bookmark">
<span itemprop="name"><?php echo esc_html( get_the_title( $p ) ); ?></span>
</a>
</li>
<?php
$position++;
endforeach;
wp_reset_postdata();
?>
</ul>
</aside>
<?php
}
add_action( 'wp_head', 'gp_related_posts_styles' );
function gp_related_posts_styles(): void {
if ( ! is_single() ) {
return;
}
?>
<style id="gp-related-posts-css">
.gp-related-posts {
margin: 50px 0;
padding: 28px 30px;
background: #fdfdfd;
border: 1px solid #e2e8f0;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.gp-related-title {
margin: 0 0 20px 0;
font-size: 1.3em;
font-weight: 600;
color: #f2005d;
text-align: center;
text-transform: uppercase;
letter-spacing: 0.8px;
}
.gp-related-list {
margin: 0;
padding-left: 1.5em;
list-style: square;
}
.gp-related-item {
margin: 0;
padding: 5px 0;
border-bottom: 1px dashed #cbd5e1;
}
.gp-related-item:last-child {
border-bottom: none;
}
.gp-related-link {
color: #1118e3;
text-decoration: none;
font-weight: 500;
font-size: 1.05em;
line-height: 1.4;
transition: color 0.2s ease;
}
.gp-related-link:hover {
color: #e43900;
}
@media (max-width: 768px) {
.gp-related-posts {
margin: 30px 0;
padding: 28px 5px;
border-radius: 0;
box-shadow: none;
}
}
</style>
<?php
}
add_action( 'save_post', 'gp_clear_related_posts_cache_lite', 10, 1 );
function gp_clear_related_posts_cache_lite( int $post_id ): void {
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return;
}
wp_cache_delete( 'gp_rel_ids_' . $post_id, 'gp_related' );
}
Giải thích cho bạn hình dung về logic sắp xếp bài viết liên quan của mình là: ưu tiên xếp theo trình tự của chuyên mục, bài nào vừa cùng chuyên mục + cùng tag thì lên đầu và ngược lại, cùng chuyên mục thôi thì xếp kế tiếp >> cùng tag là ưu tiên sau cùng. Có bao nhiêu bài liên quan thì hiện bấy nhiêu, tối đa là 4 bài.