0%

正威網路行銷工作室,專注於基隆、台北與全台客製化網頁設計,提供專業 RWD 響應式、SEO 搜尋引擎優化、品牌形象設計與網站維護託管服務。

搜尋文章
聯絡資訊
地址基隆市仁二路 220 號 5 樓
追蹤我們

WordPress 顯示相關文章:不用外掛,依分類與標籤撈出相關文章

桌上的 SEO 便利貼與網路圖示

讀者看完一篇文章,如果下面剛好有幾篇同主題的文章,很自然就會點進去繼續看。「相關文章」區塊能讓讀者多看幾頁,也替網站增加了內部連結。

先看看:你的主題或外掛可能已經有了

動手寫程式之前,先確認一下是不是已經有現成的功能:

  • 佈景主題:很多主題在「外觀 → 自訂」或主題自己的設定頁裡,就有「相關文章」的開關,先找找看。
  • 外掛:Jetpack 有「相關文章」模組;YARPP(Yet Another Related Posts Plugin)是專門做相關文章的外掛,可以調整比對方式與版型。

如果主題沒有、又不想為了這個功能多裝一個外掛,下面的程式碼就夠用了。

相關文章怎麼挑?

這篇的邏輯是:

  1. 先找「有相同標籤」的文章,標籤通常比分類更精準。
  2. 數量不夠的話,再用「相同分類」的文章補滿。
  3. 排除這篇文章自己,也排除 WordPress 預設的「未分類」,不然所有沒分類的文章都會被當成相關。
  4. 依發佈日期排序,新的文章在前面。

步驟一:撈出相關文章

程式碼加到子主題的 functions.php,或用 Code Snippets 外掛新增:

PHP
/**
 * 取得相關文章的 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

PHP
/**
 * 輸出相關文章區塊
 */
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:自動加在每篇文章內容的最後(最簡單)

傳統主題、區塊主題都適用,不用改任何範本:

PHP
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
<?php echo ahwei_related_posts_html(); ?>

輸出的內容在函式裡已經做過跳脫處理,可以直接 echo。

方法 C:區塊主題,用短代碼

區塊主題(例如 Twenty Twenty-Four)沒有 single.php 可以改,先加一個短代碼:

PHP
add_shortcode( 'related_posts', function () {
    return ahwei_related_posts_html();
} );

再到後台「外觀 → 編輯器 → 範本 → 單篇文章」,在想顯示的位置加入「短代碼」區塊,內容填 [related_posts],儲存即可。

步驟四:用 CSS 排版

用 CSS Grid 排成卡片,電腦上一排多篇,手機上會自動變成一欄:

CSS
.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 更簡單,也會自動適應手機。

延伸閱讀

讓讀者看完一篇還想再看下一篇,版面規劃佔了很大的功勞。正威網路行銷是 25 年經驗的基隆網頁設計工作室,提供客製化網頁設計與 RWD 響應式網站,歡迎來聊聊。

分享這篇文章

返回文章列表更多「Wordpress代碼教學」文章

發表留言

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

讓我們一起打造
您的專屬網站!