WooCommerce 會員中心分頁客製——欄目與導覽調整

WooCommerce 安裝完成後,「我的帳號」頁面就自動長好了一整排分頁:儀表板、訂單、下載、地址、付款方式、帳號詳細資料、登出。這套預設選單能用,但很少有店家覺得它剛剛好。有人想把「Dashboard」「Orders」這些殘留英文改成中文,有人想把用不到的「下載」分頁藏起來,也有人想加一個「我的紅利點數」或「專屬下載」自訂分頁。

問題是 WooCommerce 的會員中心不像一般頁面,沒辦法直接用區塊編輯器拖一拖就改完。它的分頁是靠 WordPress 的端點(endpoint)機制生出來的,名稱、順序、內容分別由不同的地方控制。搞不清楚哪一層該動哪裡,最常見的下場就是改完出現 404、或是改了沒反應。

這篇會把 WooCommerce 會員中心的客製拆成三個層次來講:用後台設定就能做的、要寫一小段程式碼才能做的、以及要替換範本檔才能做的。每一層對應什麼需求、程式碼貼在哪、改完還要做什麼,都會交代清楚,讓你照著做就能把會員中心的欄目與導覽調整成自己要的樣子。

WooCommerce 會員中心的分頁是怎麼長出來的

會員中心每一個分頁,本質上都是一個 WordPress 端點(endpoint)。它不是獨立頁面,而是掛在「我的帳號」這一頁底下的網址參數,例如 你的網域/my-account/orders/你的網域/my-account/edit-account/。WooCommerce 預設註冊了七個端點,對應左側選單由上到下的七個項目:

端點 key 預設選單名稱 用途
dashboard Dashboard 會員中心首頁,顯示歡迎語與快速連結
orders Orders 歷史訂單列表
downloads Downloads 可下載商品的下載連結
edit-address Addresses 帳單地址與運送地址
payment-methods Payment methods 已儲存的付款方式
edit-account Account details 姓名、信箱、密碼
customer-logout Logout 登出

理解這張表很關鍵,因為後面所有客製都是在操作這些 key。要改名稱、調順序、移除分頁,動的是這些 key 對應的「選單標籤」;要改某個分頁裡顯示的內容,動的是這些 key 對應的「內容範本」;要加一個全新分頁,則是先註冊一個新的 key,再把名稱與內容補上。

選單標籤由 woocommerce_account_menu_items 這個篩選器(filter)統一管理,它回傳一個陣列,key 就是端點代碼,值就是顯示的文字。每個分頁的內容,則是由一個動態命名的動作鉤子(hook)woocommerce_account_{端點 key}_endpoint 輸出。先記住這兩個名字,下面會反覆用到。

只想改名稱或藏掉分頁,後台就能做

如果你的需求只是把英文標籤改成中文、或把用不到的分頁拿掉,那其實不必寫任何程式碼。WooCommerce 在後台留了一個常被忽略的設定區。

路徑是 WooCommerce → 設定 → 進階 → 帳號端點。這一頁列出每個端點的「網址片段」(endpoint slug),例如訂單是 orders、地址是 edit-address。把某個欄位的文字清空,那個端點就會被停用,對應的分頁也會從選單消失。例如把「Downloads」端點的欄位清空,「下載」分頁就不見了——這招適合沒有販售可下載商品、用不到下載頁的店家。

要特別分清楚的是,這裡改的是「網址片段」,不是「選單上顯示的名稱」。換句話說,把 orders 改成 my-orders,會讓網址變成 /my-account/my-orders/,但左側選單仍然顯示「Orders」。想改選單上看到的文字,得用下一節的篩選器。所以後台這一層適合做兩件事:停用整個分頁、或調整端點的網址片段。

改完端點網址片段後,務必到 設定 → 永久連結 重新按一次「儲存變更」。WordPress 的端點規則需要重新整理(flush)才會生效,跳過這一步,新的網址片段會回傳 404。這是會員中心客製最常見的踩雷點,後面每次動到端點都要記得回來做這個動作。

用一段程式碼改選單名稱、順序與移除分頁

選單上看到的文字、項目排列順序、要不要保留某一項,全部由 woocommerce_account_menu_items 篩選器決定。把下面的程式碼放進子佈景主題的 functions.php,或自製的功能外掛裡,就能接管整個選單。

要把殘留的英文改成中文,直接覆寫對應 key 的值即可:

add_filter( 'woocommerce_account_menu_items', 'ezwps_rename_account_menu' );
function ezwps_rename_account_menu( $items ) {
    $items['dashboard']       = '會員首頁';
    $items['orders']          = '我的訂單';
    $items['downloads']       = '下載專區';
    $items['edit-address']    = '收件地址';
    $items['payment-methods'] = '付款方式';
    $items['edit-account']    = '帳號設定';
    $items['customer-logout'] = '登出';
    return $items;
}

要移除某個分頁的選單項目,用 unset() 把那個 key 拿掉。下面這段同時藏掉「下載」與「付款方式」兩個項目:

add_filter( 'woocommerce_account_menu_items', 'ezwps_remove_account_menu' );
function ezwps_remove_account_menu( $items ) {
    unset( $items['downloads'] );
    unset( $items['payment-methods'] );
    return $items;
}

這裡要提醒一個觀念:用 unset() 只是把選單項目藏起來,端點本身還在,知道網址的人仍然能直接連到那個頁面。若要連網址都停用,得回到上一節的後台「帳號端點」把欄位清空。兩種做法搭配使用,才能真正把一個分頁關乾淨。

調整順序的原理是:選單就是照陣列裡 key 的先後順序渲染的。所以重排順序等於重排這個陣列。最穩的做法是先記下「登出」項目、清掉再依想要的順序重新塞回去,確保登出永遠在最後:

add_filter( 'woocommerce_account_menu_items', 'ezwps_reorder_account_menu' );
function ezwps_reorder_account_menu( $items ) {
    $logout = $items['customer-logout'];
    unset( $items['customer-logout'] );

    $new_order = array(
        'dashboard'    => $items['dashboard'],
        'orders'       => $items['orders'],
        'edit-address' => $items['edit-address'],
        'edit-account' => $items['edit-account'],
    );
    $new_order['customer-logout'] = $logout;
    return $new_order;
}

每次儲存 functions.php 後,到前台重新整理「我的帳號」頁面就會看到變化。這一層只動選單,不涉及端點規則,所以不需要重新儲存永久連結。

新增一個自訂分頁要做的三件事

新增分頁是會員中心客製裡最完整的一條流程,常見需求像是放會員專屬下載、紅利點數、訂閱狀態、或軟體授權碼。型錄型網站把 WooCommerce 後台延伸成功能後台時,也常常需要這種自訂分頁。整個過程拆成三件事:註冊端點、加進選單、輸出內容。

第一件事是註冊一個新端點。用 WordPress 的 add_rewrite_endpoint() 函式,掛在 init 動作上。下面註冊一個叫 my-points 的端點:

add_action( 'init', 'ezwps_add_points_endpoint' );
function ezwps_add_points_endpoint() {
    add_rewrite_endpoint( 'my-points', EP_ROOT | EP_PAGES );
}

參數 EP_ROOT | EP_PAGES 告訴 WordPress 這個端點可以掛在站台根目錄與任何頁面底下,包含「我的帳號」這一頁。較新版本的 WordPress 在用 add_rewrite_endpoint() 時會自動把 key 加進查詢變數(query vars),所以不必再額外去過濾 query_vars;如果你參考到較舊的教學要你手動加 query_vars,在新環境通常可以省略。

第二件事是把這個端點加進選單。一樣用 woocommerce_account_menu_items 篩選器,但這次是新增 key。為了讓新分頁出現在「登出」之前而不是被擠到最後,先把登出抽出來,插入新項目後再放回去:

add_filter( 'woocommerce_account_menu_items', 'ezwps_add_points_menu' );
function ezwps_add_points_menu( $items ) {
    $logout = $items['customer-logout'];
    unset( $items['customer-logout'] );
    $items['my-points'] = '我的點數';
    $items['customer-logout'] = $logout;
    return $items;
}

第三件事是輸出這個分頁的內容。WooCommerce 會替每個端點動態產生一個鉤子,命名規則是 woocommerce_account_{端點 key}_endpoint。所以 my-points 對應的鉤子就是 woocommerce_account_my-points_endpoint

add_action( 'woocommerce_account_my-points_endpoint', 'ezwps_points_content' );
function ezwps_points_content() {
    $user_id = get_current_user_id();
    $points  = get_user_meta( $user_id, 'reward_points', true );
    echo '<p>您目前累積的點數為 ' . esc_html( intval( $points ) ) . ' 點。</p>';
}

做完這三件事後,回到 設定 → 永久連結 重新儲存一次。這一步絕對不能省,因為剛剛 add_rewrite_endpoint() 註冊了新的網址規則,沒有 flush 就直接點分頁,會看到 404 而不是你的內容。改好之後分頁網址會是 你的網域/my-account/my-points/,點進去就能看到剛剛輸出的文字。

端點代碼可以自由命名,但要前後一致:add_rewrite_endpoint() 註冊的 key、選單陣列的 key、內容鉤子名稱裡的 key,三處必須完全相同,少一個對不上分頁就不會運作。另外,端點的頁面標題(<h1>)預設會直接顯示端點 slug,看起來不太體面,可以用 the_title 篩選器在判斷是當前端點時改寫成中文標題。

內容比較複雜時,用範本檔取代直接 echo

上一節為了示範,直接在 PHP 函式裡用 echo 把 HTML 印出來。內容只有一兩行時這樣沒問題,但只要分頁要顯示表格、列表、條件判斷,把大量 HTML 塞進 PHP 函式會變得難維護,也不符合 WooCommerce 一貫的範本(template)寫法。比較好的做法是把輸出交給獨立的範本檔。

WooCommerce 提供 wc_get_template() 函式載入範本,並能把變數一起傳進去。把上一節的內容鉤子改成這樣:

add_action( 'woocommerce_account_my-points_endpoint', 'ezwps_points_template' );
function ezwps_points_template() {
    $points = get_user_meta( get_current_user_id(), 'reward_points', true );
    wc_get_template( 'myaccount/my-points.php', array(
        'points' => intval( $points ),
    ) );
}

接著在子佈景主題底下建立檔案 你的子主題/woocommerce/myaccount/my-points.php,這個檔案就是分頁真正的版面。剛剛傳進去的 $points 在範本裡可以直接使用:

<h3>我的紅利點數</h3>
<p>您目前累積 <strong><?php echo esc_html( $points ); ?></strong> 點。</p>

這樣 PHP 邏輯與 HTML 版面就分開了,要調版面只動範本檔,不必去翻功能程式。同樣的範本機制也適用於改寫 WooCommerce 既有分頁的版面。例如想調整訂單列表或地址頁的 HTML,可以把 WooCommerce 外掛內 templates/myaccount/ 底下對應的 .php 檔,複製到子主題的 woocommerce/myaccount/ 同名位置去改,WooCommerce 就會優先讀子主題的版本。

這裡要劃一條紅線:不要直接修改 WooCommerce 外掛資料夾裡的檔案。網路上有些舊教學會叫你去改 wp-content/plugins/woocommerce/includes/wc-account-functions.phpplugins/woocommerce/templates/ 底下的檔。這些檔案在外掛更新時會被整包覆蓋,你的所有修改都會消失,等於白費工夫。所有客製一律放在子主題或自製功能外掛裡,用篩選器、鉤子、範本覆寫的方式做,更新外掛才不會把你的調整洗掉。

不想碰程式碼的替代方案

不是每位店家都想動 functions.php。若你只想換個排版、加點視覺裝飾,而不是寫商業邏輯,有兩條免寫程式的路可走。

第一條是區塊編輯器加佈景主題的搭配。像 Blocksy 這類佈景主題,內建會員中心的版面控制,搭配 Kadence Blocks 這類區塊外掛,能在分頁內容區用拖放方式排版、加圖示、調色,不必手刻 HTML。這條路適合需求集中在「外觀」的店家,但它通常無法新增帶有自訂後端邏輯的全新端點。

第二條是專門的會員中心客製外掛。市面上有 Customize My Account for WooCommerce 這類外掛,提供視覺化介面,可以拖曳調整分頁順序、開關顯示、重新命名、新增自訂內容分頁,甚至把多個項目收進群組、依會員角色顯示不同欄目。這條路的好處是非工程背景也能管理,代價是多裝一個外掛、且進階版多半要付費。

怎麼選,取決於你的客製是偏「外觀」還是偏「功能」。只是改名稱、藏分頁、調順序,用後台設定加一小段篩選器就夠輕量,沒必要為此裝外掛;要加帶有資料邏輯的自訂分頁、又有開發能力,走 add_rewrite_endpoint() 加範本覆寫最乾淨、最好維護;完全不寫程式、需求又集中在排版美化,才考慮專用外掛或區塊主題。

把會員中心當成商店與顧客的長期接觸點來經營,調整的重點不在於塞滿功能,而在於讓顧客一眼找到他要的東西。先盤點你的會員真正會用到哪幾個分頁、用不到的果斷藏掉,再決定要不要補上專屬欄目。確認需求屬於哪一層之後,照本文對應的方法動手,並記得每次改到端點就回去重新儲存永久連結,會員中心的欄目與導覽就能調整到位。

相關文章
標籤: WooCommerce, functions.php, 我的帳號, 端點 endpoint, 會員中心客製