Hiển thị bài viết liên quan theme GeneratePress không dùng plugin

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 ^^

Hiển thị bài viết liên quan theme GeneratePress không dùng plugin
Hiển thị bài viết liên quan theme GeneratePress không dùng plugin

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 GeneratePress
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;
}
?>
<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 .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' );
}
// Bài viết liên quan GeneratePress

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.

// Bài viết liên quan GeneratePress v2
add_action( 'generate_before_comments_container', 'gp_related_posts_php84_optimized' );
function gp_related_posts_php84_optimized(): void {
if ( ! is_single() || ! is_main_query() ) {
return;
}
$current_id = get_queried_object_id();
if ( ! $current_id ) {
return;
}
$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,
'modified_date' => get_post_modified_time( 'U', true, $pid )
];
}
}
wp_reset_postdata();
if ( empty( $scored_posts ) ) {
return;
}
usort( $scored_posts, function( $a, $b ) {
if ( $b['score'] === $a['score'] ) {
return $b['modified_date'] <=> $a['modified_date'];
}
return $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;
}
?>
<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 (int) $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 .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' );
}
// Bài viết liên quan GeneratePress

Code trên là phiên bản cải tiến mình mới làm lại, tối ưu thêm về SEO và hiệu suất, code cũng khoa học hơn. Ngoài ra, logic sắp xếp sẽ ưu tiên các nội dung có thời gian cập nhật gần đây. Tức là nếu có chung chuyên mục, tag nhưng bài nào cập nhật lại gần đây thì sẽ được đưa lên đầu.

Tịnh Nguyễn
Admin

Mình hay vọc về WordPress, HTML & CSS để cải thiện trải nghiệm duyệt web trên Hocban.vn | Bạn có thể vào mục giới thiệuliên hệ để xem thêm thông tin chi tiết hơn nè.

5 5 đánh giá
Đánh giá bài viết
guest

0 Bình luận
Phản hồi nội tuyến
Xem tất cả bình luận