Skip to content

Woodmart-Child Theme 架構說明文件

版本:交接版(2026-04-29) 適用對象:接手本網站的開發團隊 前置知識:WordPress、WooCommerce、PHP、jQuery、基礎 Linux/SSH


目錄

  1. 導讀與適用對象
  2. Theme 整體架構
  3. 目錄結構地圖
  4. functions.php 模組總覽
  5. 台灣金流流程圖(重點章節)
  6. 開發守則
  7. 常見開發任務指南
  8. 第三方整合與外掛清單
  9. 效能與快取
  10. 附錄:關鍵函式速查表

1. 導讀與適用對象

本文件提供 woodmart-child 子主題的完整導覽。本網站是一個台灣 WooCommerce 電商,主要客製化集中在:

  • 台灣金流整合:藍新金流(NewebPay,含超商取貨付款 CVSCOM)、LINE Pay
  • 結帳流程:台灣地址 vs 國際地址雙路徑、運送方式條件式顯示欄位
  • 訂單狀態管理:尤其是超商取貨付款的兩段式狀態流程(選店 → 取貨付款)

⚠️ 最易出錯的區域:藍新超商取貨整合(functions.php 第 1670–2397 行),約佔全檔 1/3,務必仔細閱讀第 5 章「台灣金流流程圖」。


2. Theme 整體架構

Parent / Child Theme 關係

wp-content/themes/
├── woodmart/              ← 父主題(v7.2.5,購買自 ThemeForest)
│                            禁止直接編輯。父主題會被升級覆蓋。
└── woodmart-child/        ← 子主題(本專案的開發主場)
                             所有客製化都在這裡。
  • 為什麼用 child theme:父主題未來會升級,若直接改父主題,升級後客製會全部消失。
  • 載入順序:WordPress 自動先載 woodmart,再載 woodmart-child,後者可覆寫前者的樣式與模板。
  • JS/CSS 優先級:子主題使用 wp_enqueue_scripts priority 1000(最後載入),確保覆蓋父主題樣式。

子主題的三大覆寫機制

機制路徑用途
函式覆寫functions.php透過 hook 改變父主題或外掛行為
樣式覆寫style.css覆蓋父主題 CSS
模板覆寫woocommerce/ultimate-member/整支模板替換(同名同路徑即覆寫)

3. 目錄結構地圖

woodmart-child/
├── functions.php          ★ 主要客製檔(2397 行,第 4 章詳述)
├── style.css              自訂 CSS
├── header.php             覆寫父主題 header
├── footer.php             覆寫父主題 footer(含追蹤碼、客服按鈕等)
├── screenshot.png         主題縮圖(後台主題列表用)

├── js/
│   ├── main.js            ← 開發時編輯這個
│   └── main.min.js        ← 上線載入這個(修改 main.js 後必須 minify)

├── header-elements/       自訂 header 元件(透過 Woodmart options 嵌入)
│   ├── cart.php           購物車 widget
│   └── column.php         自訂欄位元件

├── woocommerce/           ★ WooCommerce 模板覆寫
│   ├── single-product.php 單一商品頁
│   ├── emails/            自訂訂單通知 email
│   └── myaccount/         會員中心客製

├── ultimate-member/       Ultimate Member 外掛模板覆寫(會員系統)

├── img/                   主題圖片資源(icon、社群圖示等)

└── CSS backup/            ★ 可忽略:早期 CSS 備份,與生產環境無關

js/main.jsmain.min.js 同步流程

WordPress 載入的是 main.min.js(壓縮版)。修改 main.js 後,務必執行

bash
uglifyjs wp-content/themes/woodmart-child/js/main.js \
    -o wp-content/themes/woodmart-child/js/main.min.js

版本號自動由 filemtime() 帶入,無須手動 bump(見模組 A)。


4. functions.php 模組總覽

functions.php2397 行、約 80+ 個函式/Hook。下表依功能分類,並列出起始行號,方便定位。詳細的逐函式說明見 functions.php.txt

模組行號區間主題重要程度
A1–58資產載入、版本控制、編輯器字型⭐⭐
B60–86WooCommerce 運費邏輯(免運顯示規則)⭐⭐⭐
C88–150訂單詳情頁追蹤(GA4 purchase event、affiliate)⭐⭐
D152–278藍新超商取貨訂單狀態管理(核心)⭐⭐⭐⭐⭐
E280–328後台訂單列表「需出貨」欄位⭐⭐
F330–490前端最佳化(emoji/embed 移除、jQuery migrate 移除、DNS prefetch、defer)
G492–727結帳欄位客製(地址、運送方式條件式顯示、台灣 vs 國際雙路徑)⭐⭐⭐⭐
H729–7706H 配送注意事項彈窗⭐⭐
I772–838追蹤碼(LINE Tag、FB 域名驗證、GTM)⭐⭐⭐
J840–1144覆寫父主題 woodmart_page_title(),加入 breadcrumbs⭐⭐⭐
K1147–1212訂單滯留檢查(目前停用,保留作未來啟用參考)
L1214–1262AddToAny LINE 好友、優惠券 email 限制修正⭐⭐
M1264–1279SEO:英文網址 noindex(/en_us/⭐⭐
N1281–1337LINE Pay 訂單狀態異常自動修復(5 分鐘後重檢 + 寄信通知)⭐⭐⭐⭐
O1339–1377結帳性別欄位儲存與預設值⭐⭐
P1379–1408Yoast SEO robots.txt 修正、Advanced Order Export 開放自訂 PHP
Q1410–1482學生角色機制(st- 優惠券觸發、季度 cron 清除過期)⭐⭐⭐
R1484–1597GPT 問答 shortcode + AJAX + 自訂資料表 wp_gpt_answers⭐⭐⭐
S1599–1667相關商品排除 no-show 分類⭐⭐
T1669–1802自訂超商取貨運送方式類別 WC_Custom_CVSCOM_Shipping_Method⭐⭐⭐⭐⭐
U1804–2152藍新 × 運送方式整合 JS(最複雜)⭐⭐⭐⭐⭐
V2154–2175後端阻擋 LINE Pay + 超商取貨組合⭐⭐⭐⭐
W2177–2271藍新付款參數補正(receipt 頁攔截)⭐⭐⭐⭐⭐
X2273–2372動態關閉藍新外掛超商取貨設定(option filter 攔截)⭐⭐⭐⭐⭐
Y2374–2397藍新自動跳轉時間調整(10s → 3s)⭐⭐

模組 D、T、U、V、W、X 共同構成「藍新超商取貨完整整合」,請務必合在一起閱讀。


5. 台灣金流流程圖(重點章節)

5.1 藍新金流超商取貨完整流程

藍新超商取貨有兩種付款模式

模式藍新代號_nwpSelectedPayment_CVSCOMNotPayed說明
超商取貨付款CVSCOM=2CVSCOMPayed0顧客到超商取貨時才付錢(貨到付款)
超商取貨不付款CVSCOM=1Credit 或其他1線上先付款,到超商只取貨

完整流程(以「超商取貨付款 / CVSCOM=2」為例)

[1] 顧客在購物車選「超商取貨」運送方式

     │  → JS(模組 G、U)動態:
     │     - 隱藏地址欄位
     │     - 顯示藍新外掛的「nwp_selected_payments」下拉
     │     - 顯示 #CVSCOMNotPayed checkbox(視覺隱藏但保留 DOM)
     │     - 隱藏 LINE Pay 付款選項

[2] 顧客選擇「超商取貨付款」(nwp_selected_payments = CVSCOMPayed)

     │  → JS autoToggleCheckbox():CVSCOMNotPayed = unchecked (=0)

[3] 顧客填妥資料,按「結帳」

     │  → 後端 woocommerce_after_checkout_validation
     │     ├─ prevent_linepay_with_store_pickup(模組 V):擋掉 LINE Pay+超商
     │     └─ newebpay_handle_non_cvscom_shipping(模組 W 上半):清資料

     │  → WooCommerce 建立訂單 → 進入 receipt 頁面

[4] receipt 頁渲染前 newebpay_intercept_before_payment_page(模組 W):
     │  ├─ 確認運送=超商 + 付款=CVSCOMPayed
     │  └─ 補正 _CVSCOMNotPayed = 0

     │  → option_woocommerce_newebpay_settings filter(模組 X):
     │     └─ 動態決定外掛是否啟用 CVSCOMPayed/CVSCOMNotPayed 設定

[5] 藍新外掛產生加密表單,3 秒後自動 POST 至藍新(模組 Y)

[6] 藍新導向「選擇門市」頁面 → 顧客選店 → 回傳第一次 callback

     │  → WooCommerce 訂單狀態被外掛改為 processing/completed
     │  → ❗ newebpay_cvscom_fix_status(模組 D)攔截:
     │     檢查訂單備註,若只有「店家:」沒有「付款時間」
     │     → 強制改回 pending(等待顧客取貨付款)

[7] 顧客到超商取貨並付款 → 藍新回傳第二次 callback(含「付款時間」)

     │  → 訂單備註出現「藍新金流交易序號 + 付款時間」
     │  → newebpay_cvscom_fix_status 此時不攔截,狀態 = completed ✅

關鍵函式速查(藍新整合)

函式行號觸發時機用途
WC_Custom_CVSCOM_Shipping_Method1681WC 載入運送方式註冊「超商取貨」運送方式
add_custom_cvscom_shipping_method1799woocommerce_shipping_methods將上述類別加入 WC
my_hide_shipping_when_free_is_available62計算運費時免運時仍顯示超商取貨、6H
custom_checkout_field_script515wp_footer(結帳)條件式顯示地址欄位
wps_select_checkout_field_process671woocommerce_checkout_process後端驗證地址欄位
newebpay_shipping_payment_integration1816wp_footer(結帳)超商 × 付款方式整合 JS(最重要)
prevent_linepay_with_store_pickup2160woocommerce_after_checkout_validation擋 LINE Pay + 超商組合
newebpay_handle_non_cvscom_shipping2181woocommerce_checkout_posted_data非超商時清掉 CVSCOM 欄位
newebpay_intercept_before_payment_page2221woocommerce_receipt_newebpay(priority 0)補正訂單 meta,最後攔截點
newebpay_filter_cvscom_settings2278option_woocommerce_newebpay_settings動態關閉外掛超商付款設定
newebpay_modify_auto_submit_time2381wp_footer(order-pay)自動跳轉 10s → 3s
newebpay_cvscom_fix_status173woocommerce_order_status_changed(priority 999)狀態回退:選店後保持 pending
newebpay_cvscom_manual_update238woocommerce_payment_complete後台手動「更新交易狀態」時補正

5.2 LINE Pay 流程與限制

  • 外掛:woocommerce-gateway-linepay
  • 限制:LINE Pay 不支援超商取貨,前端 + 後端雙重擋(模組 U + V)。
  • 狀態異常自動修復(模組 N):
    訂單由 processing → failed
    
    log_status() 排程一次性 cron(5 分鐘後)
    
    check_linepay_success_handler()
         ├─ 讀取 _linepay_payment_status
         ├─ 若 = 'confirmed',改回 processing
         └─ 寄信通知 4 位管理員(hello/joanna/Ruby/DD@chunling.com.tw)

5.3 排錯入口

症狀檢查點
超商取貨訂單一下單就變 completednewebpay_cvscom_fix_status 是否被掛上 priority 999
訂單備註有「店家:」但沒「付款時間」屬於正常(顧客已選店、未取貨),狀態應為 pending
結帳頁出現「LINE Pay 不支援超商」預期行為,模組 V 後端阻擋
藍新導頁顯示「無此付款方式」模組 X newebpay_filter_cvscom_settings 是否錯誤關閉設定
後台儲存藍新外掛設定無效模組 X 的 if (is_admin()) 早退是否被破壞
結帳沒選運送方式就顯示超商付款選項模組 U isStorePickingShipping() 的「只有一個運送方式」邏輯

6. 開發守則

6.1 絕對不可違反

  1. 絕不直接編輯父主題 woodmart/——升級會洗掉所有改動。
  2. 絕不直接編輯外掛資料夾——所有客製透過 hook 在 child theme 完成。
  3. 絕不在 wp-config.php 之外硬編 API Key——使用 define('OPENAI_API_KEY', ...)
  4. AJAX handler 必須 check_ajax_referer()(防 CSRF)。
  5. 所有 $_GET / $_POST 必須 sanitizeabsintsanitize_text_field 等)。
  6. 修改 functions.php 後必跑 php -l 語法檢查
    bash
    php -l wp-content/themes/woodmart-child/functions.php
  7. 修改 main.js 後必同步 main.min.js(見第 3 章)。

6.2 Hook 優先級慣例

優先級用途例子
0最早攔截newebpay_intercept_before_payment_page
5早期過濾 POST 資料newebpay_handle_non_cvscom_shipping
10WordPress 預設大多數 hook
15資產 URL 過濾crave_script_version_with_filemtime
100運費過濾my_hide_shipping_when_free_is_available
999訂單狀態強制修正newebpay_cvscom_fix_status
1000子主題資產載入woodmart_child_enqueue_styles
9999最晚攔截外掛設定newebpay_filter_cvscom_settings

6.3 Cron 任務管理

  • 自訂排程頻率寫在 add_quarterly_cron_schedule()(line 1460)
  • 排程任務必須在 register_deactivation_hook() 中清除,避免主題停用後成為孤兒
  • 使用 [WP-Crontrol] 外掛可在後台檢視所有 cron 任務

6.4 偵錯模式

php
// wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
bash
tail -f wp-content/debug.log

functions.php 中已有大量 error_log()console.log()(特別在藍新整合區),上線前可考慮關閉但不要刪除(出問題時是救命用)。


7. 常見開發任務指南

7.1 新增 WooCommerce 客製 Hook

php
add_action('woocommerce_xxx_hook', 'my_callback', 10, $arg_count);
function my_callback($args) {
    // 1. 確認觸發條件(運送/付款/狀態)
    // 2. 操作前先讀取現有 meta 避免覆蓋
    // 3. 結束時 $order->save()
}

測試清單:

  • [ ] 用宅配 + 信用卡測試
  • [ ] 用 6H 配送 + 信用卡測試
  • [ ] 用超商取貨付款測試
  • [ ] 用超商取貨不付款測試
  • [ ] 用 LINE Pay 測試(注意不可選超商)
  • [ ] 國際地址結帳測試

7.2 修改結帳欄位

  1. set_checkout_field_default_value() 加入新欄位的預設值(line 1364)
  2. wps_select_checkout_field_process() 加入後端驗證(line 671)
  3. custom_checkout_field_script() 加入前端條件顯示(line 515)
  4. update_user_gender_meta() 模式儲存到 user meta(line 1346)

7.3 新增 shortcode(含 AJAX)

參考 gpt_question_button_shortcode(line 1485)+ gpt_handle_ajax_request(line 1520)模式:

  1. add_shortcode() 註冊
  2. wp_enqueue_script + wp_localize_script 傳 nonce
  3. wp_ajax_xxx + wp_ajax_nopriv_xxx 雙註冊
  4. handler 內 check_ajax_referer()
  5. 回應用 wp_send_json_success / wp_send_json_error

7.4 Template Override

bash
# 從父主題或外掛複製到子主題(保留路徑)
cp wp-content/themes/woodmart/woocommerce/checkout/form-checkout.php \
   wp-content/themes/woodmart-child/woocommerce/checkout/form-checkout.php

⚠️ Template override 是雙刃劍:父主題/WooCommerce 升級時可能不相容,需定期回頭比對。


8. 第三方整合與外掛清單

金流

外掛用途
newebpay-payment藍新金流主要外掛(含超商取貨)
newebpay(舊版)已被 newebpay-payment 取代,但部分 meta key 沿用
woocommerce-gateway-linepayLINE Pay

追蹤

  • Google Tag Manager(GTM-PC8K325)
  • Google Analytics 4(G-Z5C8WK0J0F)
  • Facebook Pixel + PixelYourSite Pro
  • LINE Tag(tagId: 7873c94a-88a8-4847-a533-5fff1f881a8b
  • AddToAny(含自訂 LINE 加好友)
  • VBTrax 聯盟追蹤(shortcode [affiliates]

安全

  • iThemes Security(Better WP Security)
  • Security Ninja Premium
  • Two-Factor Authentication
  • Advanced noCAPTCHA & reCAPTCHA

SEO / 內容

  • Yoast SEO(含英文版 noindex 規則)
  • Breadcrumb NavXT(bcn_display()
  • Advanced Order Export For WooCommerce(已開放自訂 PHP)

會員 / 多語

  • Ultimate Member(會員系統)
  • WPML(多語,若啟用)

維護

  • All-in-One WP Migration(備份/搬遷)
  • WP-Crontrol(cron 管理)
  • Health Check & Troubleshooting(mu-plugin)

9. 效能與快取

機制說明
object-cache.phpRedis/Memcached 物件快取(wp-content/object-cache.php
W3 Total Cache頁面/瀏覽器/資料庫快取
資產 filemtime 版控crave_script_version_with_filemtime()(line 17)替換所有主題 CSS/JS 的 ?ver=,瀏覽器自動破快取
wp_gpt_answersGPT 回應快取(避免重複呼叫 OpenAI)
woodmart_exclude_cat_* transient排除分類的商品 ID 快取 1 小時(line 1646)

10. 附錄:關鍵函式速查表

資產 / 前端最佳化

函式行號用途
woodmart_child_enqueue_styles5載入子主題 CSS/JS
crave_script_version_with_filemtime17自動版本號
add_custum_fontfamily47TinyMCE 中英文字型
crave_disable_emojis373移除 emoji 載入
crave_disable_embeds419移除 oEmbed
crave_remove_jquery_migrate458移除 jQuery Migrate
dns_prefetch466加上 DNS prefetch hints

訂單 / 運費

函式行號用途
my_hide_shipping_when_free_is_available62免運顯示規則
wh_CustomReadOrder90GA4 purchase event
affiliates_trank121VBTrax 聯盟追蹤 shortcode
custom_shop_order_column281後台訂單欄位
custom_orders_list_column_content296「需出貨」標記內容
log_status1289LINE Pay 狀態異常排程
check_linepay_success_handler1310LINE Pay 自動修復
ctk_check_order_stay_too_long1185取消過久未付款訂單(停用中)

藍新超商整合(最關鍵)

函式行號用途
newebpay_cvscom_fix_status173選店後狀態回退 pending
newebpay_cvscom_manual_update238後台手動更新狀態補正
WC_Custom_CVSCOM_Shipping_Method1681自訂超商取貨運送方式類別
newebpay_shipping_payment_integration1816結帳頁 JS 整合
prevent_linepay_with_store_pickup2160擋 LINE Pay+超商
newebpay_handle_non_cvscom_shipping2181清非超商的 CVSCOM 資料
newebpay_intercept_before_payment_page2221receipt 頁補正 meta
newebpay_filter_cvscom_settings2278動態關閉外掛設定
newebpay_modify_auto_submit_time2381自動跳轉 3 秒

結帳欄位

函式行號用途
filter_default_address_fields498設定地址欄位非必填
custom_checkout_field_script515動態顯示/隱藏欄位 JS
wps_select_checkout_field_process671後端驗證
checkout_action_wp_footer7316H 注意事項彈窗
update_user_gender_meta1346性別存 user meta
set_checkout_field_default_value1364性別欄位預設值

學生角色

函式行號用途
add_student_role1411註冊 role
add_student_role_on_coupon_use1425st- 開頭優惠券觸發
check_and_remove_expired_student_roles1439季度移除超過 1 年的角色
add_quarterly_cron_schedule1460季度排程
schedule_quarterly_student_role_check1470註冊 cron
deactivate_quarterly_student_role_check1478停用主題時清除 cron

GPT 問答

函式行號用途
gpt_question_button_shortcode1485shortcode 渲染
gpt_enqueue_scripts1511載入 JS + nonce
gpt_handle_ajax_request1520AJAX handler(OpenAI 呼叫 + 快取)

其他

函式行號用途
set_line_tag773LINE Tag 追蹤
set_fb_verification_to_meta807FB 域名驗證 meta
set_gtm829GTM 載入
woodmart_page_title850覆寫父主題頁標題加 breadcrumbs
addtoany_add_follow_services1215AddToAny LINE 加好友
wc_check_coupon_is_valid1240優惠券 email 限制(不分大小寫)
setNoindexIfEn1272英文版 /en_us/ noindex
wpwc_fix_yoast_seo_robots_txt1391修正 Yoast 對 robots.txt 的覆蓋
woodmart_exclude_category_from_related_products1608相關商品排除 no-show 分類

文件維護

  • 本文件對應 functions.php 的時間點為 2026-04-29(git commit be138e14
  • 行號可能因後續修改而漂移,請以函式名稱為主、行號為輔
  • 如做大幅重構,建議同步更新本文件與 functions.php.txt