0%

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

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

WordPress 顯示文章閱讀次數:不用外掛的程式碼寫法(含快取網站解法)

手指點選搜尋列

想讓讀者看到每篇文章「已經有多少人看過」,或是自己想知道哪幾篇最受歡迎,最直覺的做法是在文章上顯示閱讀次數。

WordPress 本身沒有這個功能。裝外掛(例如 Post Views Counter)當然可以,但如果你只需要一個簡單的數字,用幾段程式碼就能做到,網站也少一個要維護、要更新的外掛。

這篇會一步一步完成:

  1. 記錄每篇文章被看了幾次(管理員自己看、搜尋引擎爬蟲都不算)
  2. 把次數顯示在文章頁
  3. 在後台文章列表多一欄「閱讀次數」
  4. 做一個「熱門文章」排行
  5. 網站有裝快取外掛時,數字不會動的解決方法

開始之前:程式碼要放在哪裡?

下面的 PHP 程式碼都是加到主題的 functions.php。建議用下面兩種方式之一,不要直接改主題本身的檔案,不然主題一更新,你加的程式碼就會被覆蓋掉:

  • 子主題(Child Theme):在子主題的 functions.php 最後面貼上。
  • Code Snippets 外掛:到後台「外掛 → 安裝外掛」搜尋 Code Snippets,新增一段程式碼貼上即可,不用碰檔案。

動手前記得先備份網站,改錯時才能馬上還原。

步驟一:記錄閱讀次數

每篇文章的閱讀次數存在文章的自訂欄位(post meta)裡,欄位名稱叫 views。

PHP
/**
 * 讀取文章閱讀次數 (回傳加上千分位的數字,例如 1,234)
 */
function ahwei_get_post_views( $post_id = null ) {
    $post_id = $post_id ? $post_id : get_the_ID();
    $count   = (int) get_post_meta( $post_id, 'views', true );
    return number_format_i18n( $count );
}

/**
 * 每開一次文章,閱讀次數 +1
 * 管理員、編輯自己看文章不算;搜尋引擎爬蟲不算
 */
function ahwei_set_post_views() {
    if ( ! is_singular( 'post' ) || is_preview() ) {
        return;
    }
    if ( current_user_can( 'edit_posts' ) ) {
        return;
    }
    $agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
    if ( preg_match( '/bot|crawl|spider|slurp/i', $agent ) ) {
        return;
    }
    $post_id = get_queried_object_id();
    $count   = (int) get_post_meta( $post_id, 'views', true );
    update_post_meta( $post_id, 'views', $count + 1 );
}
add_action( 'template_redirect', 'ahwei_set_post_views' );

幾個重點:

  • 用 template_redirect 這個時機計數,只有前台真的打開文章時才會執行,不會在後台或 RSS 被重複計算。
  • 舊版教學常把計數掛在 get_header,它跟著主題的 header 範本走,換了主題或主題寫法不同就容易漏算、重複算;template_redirect 是 WordPress 核心每次載入前台頁面都會經過的時機,比較穩定。
  • 如果你以前用過別的教學、欄位名稱不是 views(例如 post_views_count),把程式碼裡的 views 改成原本的名稱,就能沿用累積的數字。

步驟二:在文章頁顯示「幾次閱讀」

傳統主題(有 single.php)

打開子主題的 single.php,在想顯示的位置(通常是標題下方、日期旁邊)加上:

PHP
<span class="post-views"><?php echo ahwei_get_post_views(); ?> 次閱讀</span>

區塊主題(例如 Twenty Twenty-Four,沒有 single.php)

區塊主題是用「網站編輯器」排版,沒有 single.php 可以改。先在 functions.php 加一個短代碼:

PHP
add_shortcode( 'post_views', function () {
    return ahwei_get_post_views() . ' 次閱讀';
} );

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

步驟三:後台文章列表多一欄「閱讀次數」

不用一篇一篇點進去看,在後台「文章 → 所有文章」直接列出每篇的次數:

PHP
add_filter( 'manage_posts_columns', function ( $columns ) {
    $columns['post_views'] = '閱讀次數';
    return $columns;
} );

add_action( 'manage_posts_custom_column', function ( $column, $post_id ) {
    if ( 'post_views' === $column ) {
        echo ahwei_get_post_views( $post_id );
    }
}, 10, 2 );

步驟四:熱門文章排行

有了閱讀次數,就能依次數排序,做出「熱門文章」清單。放在側邊欄、文章最後都很適合:

PHP
$popular = new WP_Query( array(
    'post_type'           => 'post',
    'posts_per_page'      => 5,
    'meta_key'            => 'views',
    'orderby'             => 'meta_value_num',
    'order'               => 'DESC',
    'ignore_sticky_posts' => true,
) );

if ( $popular->have_posts() ) {
    echo '<ol class="popular-posts">';
    while ( $popular->have_posts() ) {
        $popular->the_post();
        printf(
            '<li><a href="%s">%s</a>(%s 次閱讀)</li>',
            esc_url( get_permalink() ),
            esc_html( get_the_title() ),
            ahwei_get_post_views()
        );
    }
    echo '</ol>';
    wp_reset_postdata();
}

meta_value_num 會把欄位當成數字排序;用 meta_value 的話會變成文字排序,「9」會排在「100」前面。

裝了快取外掛,閱讀次數就不動了?

這是最常遇到的問題。WP Rocket、LiteSpeed Cache、W3 Total Cache 這類快取外掛,會把文章頁存成靜態 HTML 直接送給訪客,PHP 根本沒有執行,步驟一的計數程式自然不會跑。

解法是讓瀏覽器在頁面載入後,另外呼叫一次 WordPress 的 REST API 來計數。快取的是頁面,這個呼叫不會被快取:

PHP
// 1) 建立計數用的 API:POST /wp-json/ahwei/v1/views/文章ID
add_action( 'rest_api_init', function () {
    register_rest_route( 'ahwei/v1', '/views/(?P<id>\d+)', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true',
        'callback'            => function ( $request ) {
            $post_id = (int) $request['id'];
            if ( 'post' !== get_post_type( $post_id ) || 'publish' !== get_post_status( $post_id ) ) {
                return new WP_Error( 'not_found', 'Not found', array( 'status' => 404 ) );
            }
            $count = (int) get_post_meta( $post_id, 'views', true ) + 1;
            update_post_meta( $post_id, 'views', $count );
            return array( 'views' => $count );
        },
    ) );
} );

// 2) 文章頁載入後,由瀏覽器呼叫上面的 API
add_action( 'wp_footer', function () {
    if ( ! is_singular( 'post' ) || current_user_can( 'edit_posts' ) ) {
        return;
    }
    $url = rest_url( 'ahwei/v1/views/' . get_the_ID() );
    printf( '<script>fetch(%s,{method:"POST"});</script>', wp_json_encode( $url ) );
} );

改用這個寫法時,記得把步驟一的 add_action( 'template_redirect', 'ahwei_set_post_views' ); 那一行刪掉,不然沒有快取的時候會一次算兩次。

這個 API 任何人都能呼叫,理論上有人可以故意灌次數。閱讀次數只是顯示用的參考數字,一般部落格這樣就夠了;要做正式的流量分析,請用 Google Analytics 4。

常見問題

自己重新整理頁面,數字會一直增加嗎?

登入後台的管理員、編輯不會被計算(程式碼裡的 current_user_can( 'edit_posts' ))。一般訪客重新整理確實會再加一次;如果想「同一個人一天只算一次」,可以再搭配 Cookie 判斷,但對大多數網站來說,簡單的計數就很夠用了。

閱讀次數跟 Google Analytics 的數字對不起來?

正常。兩者的計算方式不同:這裡是「文章頁被打開幾次」,GA4 會排除更多機器流量、也有自己的工作階段規則。對外顯示用這個計數,分析流量請以 GA4 為準。

想一次清掉所有閱讀次數重新計算?

到資料庫的 wp_postmeta 資料表,刪除 meta_key 是 views 的資料就會全部歸零。操作資料庫前一定要先備份。

延伸閱讀

網站是請人做的、不方便自己改程式,或是 WordPress 網站越改越亂,想整個重新規劃成好管理的網站?正威網路行銷是有 25 年經驗的基隆網頁設計工作室,也服務台北與全台客戶,歡迎來聊聊。

分享這篇文章

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

發表留言

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

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