
讀者看完一篇文章,如果下面剛好有幾篇同主題的文章,很自然就會點進去繼續看。「相關文章」區塊能讓讀者多看幾頁,也替網站增加了內部連結。
先看看:你的主題或外掛可能已經有了
動手寫程式之前,先確認一下是不是已經有現成的功能:
- 佈景主題:很多主題在「外觀 → 自訂」或主題自己的設定頁裡,就有「相關文章」的開關,先找找看。
- 外掛:Jetpack 有「相關文章」模組;YARPP(Yet Another Related Posts Plugin)是專門做相關文章的外掛,可以調整比對方式與版型。
如果主題沒有、又不想為了這個功能多裝一個外掛,下面的程式碼就夠用了。
相關文章怎麼挑?
這篇的邏輯是:
- 先找「有相同標籤」的文章,標籤通常比分類更精準。
- 數量不夠的話,再用「相同分類」的文章補滿。
- 排除這篇文章自己,也排除 WordPress 預設的「未分類」,不然所有沒分類的文章都會被當成相關。
- 依發佈日期排序,新的文章在前面。
步驟一:撈出相關文章
程式碼加到子主題的 functions.php,或用 Code Snippets 外掛新增:
/**
* 取得相關文章的 ID:先找相同標籤,不夠再用相同分類補
*/
function ahwei_get_related_post_ids( $post_id, $number = 4 ) {
$found = array();
// 「未分類」這種預設分類不拿來比對
$cat_ids = array_diff(
wp_get_post_categories( $post_id ),
array( (int) get_option( 'default_category' ) )
);
$rules = array(
'tag__in' => wp_get_post_tags( $post_id, array( 'fields' => 'ids' ) ),
'category__in' => array_values( $cat_ids ),
);
foreach ( $rules as $key => $term_ids ) {
if ( empty( $term_ids ) || count( $found ) >= $number ) {
continue;
}
$query = new WP_Query( array(
$key => $term_ids,
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => $number - count( $found ),
'post__not_in' => array_merge( array( $post_id ), $found ),
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'fields' => 'ids',
) );
$found = array_merge( $found, $query->posts );
}
return $found;
}幾個重點:
'fields' => 'ids'只取文章 ID,不會動到目前頁面的文章資料,也比較省資源。'no_found_rows' => true告訴 WordPress 不用計算總共有幾篇(我們不需要分頁),查詢會快一點。'ignore_sticky_posts' => true讓置頂文章不會硬擠進相關文章裡。
步驟二:輸出相關文章的 HTML
/**
* 輸出相關文章區塊
*/
function ahwei_related_posts_html( $post_id = null ) {
$post_id = $post_id ? $post_id : get_the_ID();
$ids = ahwei_get_related_post_ids( $post_id, 4 );
if ( empty( $ids ) ) {
return '';
}
$html = '<section class="related-posts"><h2>推薦閱讀</h2><ul>';
foreach ( $ids as $id ) {
$html .= '<li><a href="' . esc_url( get_permalink( $id ) ) . '">';
if ( has_post_thumbnail( $id ) ) {
$html .= get_the_post_thumbnail( $id, 'medium', array( 'alt' => '', 'loading' => 'lazy' ) );
}
$html .= '<span>' . esc_html( get_the_title( $id ) ) . '</span></a></li>';
}
$html .= '</ul></section>';
return $html;
}- 有設定精選圖片的文章會顯示縮圖,沒有的就只顯示標題。
- 縮圖的替代文字設成空白,因為旁邊已經有文章標題,螢幕報讀軟體就不會把同一件事唸兩次。
- 想顯示 6 篇,把
4改成6;標題「推薦閱讀」也可以自己改。
步驟三:放到文章頁
下面三種放法擇一使用,同時用兩種會出現兩個相關文章區塊。
方法 A:自動加在每篇文章內容的最後(最簡單)
傳統主題、區塊主題都適用,不用改任何範本:
add_filter( 'the_content', function ( $content ) {
if ( is_singular( 'post' ) && get_the_ID() === get_queried_object_id() ) {
$content .= ahwei_related_posts_html();
}
return $content;
}, 20 );方法 B:傳統主題,放在範本的指定位置
想放在作者資訊或留言區上面等特定位置,打開子主題的 single.php,在 the_content() 後面、你想要的位置加上:
<?php echo ahwei_related_posts_html(); ?>輸出的內容在函式裡已經做過跳脫處理,可以直接 echo。
方法 C:區塊主題,用短代碼
區塊主題(例如 Twenty Twenty-Four)沒有 single.php 可以改,先加一個短代碼:
add_shortcode( 'related_posts', function () {
return ahwei_related_posts_html();
} );再到後台「外觀 → 編輯器 → 範本 → 單篇文章」,在想顯示的位置加入「短代碼」區塊,內容填 [related_posts],儲存即可。
步驟四:用 CSS 排版
用 CSS Grid 排成卡片,電腦上一排多篇,手機上會自動變成一欄:
.related-posts ul {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
margin: 0;
padding: 0;
list-style: none;
}
.related-posts a {
display: block;
color: inherit;
text-decoration: none;
}
.related-posts img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px;
}
.related-posts span {
display: block;
margin-top: 8px;
font-weight: 600;
line-height: 1.5;
}
.related-posts a:hover span {
text-decoration: underline;
}CSS 可以加在「外觀 → 自訂 → 額外 CSS」;區塊主題則在網站編輯器的「樣式」裡找「額外 CSS」。縮圖用 object-fit: cover 裁成一樣的比例,原理可以參考CSS 圖片填滿 div 不變形。
舊版寫法的問題
這篇文章舊版的程式碼有幾個地方現在不建議再用:
query_posts():它會直接改掉頁面原本的主查詢,放在文章頁裡,後面的留言、側邊欄或條件判斷都可能出錯,WordPress 官方文件也建議不要在範本裡使用。另外建立一個WP_Query才是正確的做法。orderby=rand隨機排序:每次顯示都要資料庫把文章打亂重排,文章多的時候很耗資源;網站有快取外掛時,隨機結果也會被固定住,達不到效果。showposts參數:已經被posts_per_page取代。- float 排版與舊的瀏覽器前綴:原本的 CSS 用
float排列,還加了-moz-、-webkit-前綴,現在用 Grid 更簡單,也會自動適應手機。
延伸閱讀
- WordPress 顯示文章閱讀次數:不用外掛的程式碼寫法(含快取網站解法)
- WordPress 內部連結怎麼做?SEO 觀念與自動關鍵字連結的正確寫法
- CSS 圖片填滿 div 不變形:object-fit: cover 用法與固定比例寫法
讓讀者看完一篇還想再看下一篇,版面規劃佔了很大的功勞。正威網路行銷是 25 年經驗的基隆網頁設計工作室,提供客製化網頁設計與 RWD 響應式網站,歡迎來聊聊。







發表留言
還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。