建立 2026-09-02 ・ 對照 at-inwin-plugin v0.60.0 + atelement-widgets v3.15.4 逐行核對
・ 前後端共用參考
接下來要動三件事:megamenu 的地區切換、商品/分類的地區語系隱藏、 商品/分類的地區語系資料讀取。三件都同時牽涉前後端,所以先把兩邊的現況畫成同一張圖, 避免各自照著自己那半邊的假設往下做。
兩邊的程式碼都是逐行讀過才寫的,每條結論都附 檔案:行號,可以直接查證;
站上的部分是實測,附了指令與數字。如果有哪裡跟你的理解對不上,
很可能是我讀錯了——請直接指出來。
atelement-widgets,
它的分類與商品查詢刻意繞過整個 WordPress query API ⇒ 沒有任何 hook 掛得上去,
需要前端配合改 widget。
WP_Query、pre_get_posts 也有跑,
只是我們自己要求 is_main_query() 而主動放行了。
檔案:行號。
region 與 locale 是兩條完全獨立的解析鏈,各有自己的快取、白名單與 fallback,
彼此不交互作用。兩者都由後端 iTemplateRenderer 提供唯一實作。
flowchart TD
subgraph R["resolve_current_region() iTemplateRenderer.php:181-207"]
R0{"static cache
已有值?"} -->|是| RH["直接回傳"]
R0 -->|否| R1{"$_GET['region']
在白名單?"}
R1 -->|是| RW["write_region_cookie()
種 30 天 cookie"] --> RC["回傳"]
R1 -->|否 / 不存在| R2{"$_COOKIE
inwin_region
在白名單?"}
R2 -->|是| RC
R2 -->|否| R3["fallback 'main'"] --> RC
end
subgraph L["resolve_current_locale() iTemplateRenderer.php:310-324"]
L0{"function static
cache 已有值?"} -->|是| LH["直接回傳"]
L0 -->|否| L1["apply_filters
('wpml_current_language')"]
L1 -->|null| L2["'en'"] --> LC["回傳"]
L1 -->|有值| L3{"在 locale_mapping
對照表?"}
L3 -->|是| L4["內部 4 字母碼
zh-hant → hant"] --> LC
L3 -->|否| L5["⚠️ 原值穿透
pt-pt → 'pt-pt'"] --> LC
end
style RW fill:#fff3cd,stroke:#9a6700
style L5 fill:#fdf0f0,stroke:#8b1d1d
style R3 fill:#eef,stroke:#556
style L2 fill:#eef,stroke:#556
圖 1 — 兩條解析鏈。唯一會產生副作用(種 cookie)的是 region 的第一步。
| region | locale | |
|---|---|---|
| 解析白名單 | americas / apac / emea / other / mainiTemplateRenderer.php:144 |
對照表 9 種 + eniTemplateRenderer.php:249-260 |
| 可存進隱藏設定的值 | 4 個(不含 main) RegionRegistry.php:32 |
10 個(含 en)RegionRegistry.php:112-120 |
| 快取形式 | class property $cached_region有 reset_cached_region() |
函式內 static,無重置點 |
| 未知值的行為 | 忽略,往下一步走 | 原值穿透(?? $wpml_locale) |
| 寫入 cookie | 只有 ?region= 命中白名單時iTemplateRenderer.php:188 |
不寫 |
resolve_current_locale() 用的是函式內 static $cached(:311-312),
沒有對應的 reset。若任何程式在 WPML 就緒前呼叫它一次,
apply_filters('wpml_current_language', null) 會回 null,
該 request 的 locale 就永久固定成 'en'(:317),
之後所有翻譯、locale 隱藏判定、樣板 locale patch 全部退回英文。
目前最早的呼叫點是 pre_get_posts(HiddenVisibilityGate.php:435),
實務上晚於 WPML init——但這是時序耦合,不是結構保證。任何新增的早期 hook 都可能引爆它。
write_region_cookie()(iTemplateRenderer.php:217-227):
名稱 inwin_region、30 天、Path=/、Secure、
HttpOnly=false(刻意讓 JS 可讀寫)、SameSite=Lax。
Secure 是硬寫死的(:223)。headers_sent() 時靜默放棄(:218),沒有任何訊號。?region= 的產生者不在這個 repo 內。
實際的產生者是前端的 megamenu(見下節)。| 模組 | region | locale | 備註 |
|---|---|---|---|
iTemplate(標題 filter) | ✓ | ✓ | iTemplate.php:144,167 |
HiddenVisibilityGate | ✓ | ✓ | 三處 :396,434,551 |
iValue/Adapter/Product/Text | ✓ | ✓ | 五處 |
ProductCompareTableMerger | ✓ | ✓ | :39 |
ProductCategoryTranslation | ✗ | ✓ | 分類側完全沒有 region ( rg region modules/ProductCategory/ 零命中) |
iValue/Adapter/ProductCategory/Text | ✗ | ✓ | |
iValue/Adapter/ProductCategory/Gallery | ✗ | ✓ |
這是最容易誤解的一段。「商品基本資訊」與「iTemplate 樣板資料」不是同一套 key、也不是同一種疊加規則。
flowchart LR
subgraph A["(A) 商品基本欄位 ProductFieldResolver"]
direction TB
A1["地區軸
_product_{field}_{region}"] -->|非空即回| AR(["回傳"])
A2["語系軸
_product_{field}_{locale}"] -->|非空即回| AR
A3["基準
原生欄位 post_title 等"] --> AR
A1 -.->|空| A2 -.->|空| A3
AX["❌ 沒有交叉座標
region+locale 不存在"]
end
subgraph B["(B) iTemplate 樣板 iTemplateVariantKeys"]
direction TB
B0["基準
itemplate_*_main_en"] --> BM["array_merge
後套者覆蓋"]
B1["語系軸 main_{locale}"] --> BM
B2["地區軸 {region}_en"] --> BM
B3["交叉 {region}_{locale}
key space 保留
目前無 UI 寫入"] --> BM
BM --> BR(["合併結果"])
end
style AX fill:#fdf0f0,stroke:#8b1d1d
style B3 fill:#f2f3f5,stroke:#999,stroke-dasharray: 4 3
圖 2 — 兩套座標系統。左邊「先返回者贏」,右邊「後套者覆蓋」,但兩者的淨效果都是地區蓋語系。
| (A) 商品基本欄位 | (B) iTemplate 樣板 | |
|---|---|---|
| 實作 | ProductFieldResolver::resolve():85-101 |
iTemplateVariantKeys::candidate_meta_keys():62-67 |
| 機制 | 三段 if,先返回者贏 | 陣列順序即套用順序,後套者覆蓋 |
| 疊加結果 | 地區蓋語系(裁定 D8)——反轉成本=對調兩段程式碼 | |
| 交叉座標 | 不存在 | key space 保留、無 UI 寫入、 寫入 API 明確拒絕 |
| 分類側 | ✗ 沒有地區軸(plm#19) | ✓ 有效(走 get_term_meta) |
訪客在 (apac, hant) 下,若該商品有 _product_title_apac,
就會拿到 APAC 版(多半是英文),而 _product_title_hant 這個繁中翻譯
永遠讀不到。這是 D8 裁定的直接後果、不是 bug,但它意味著
「設了地區內容的商品,在該地區失去所有語系翻譯」。樣板側因為有交叉 key space 而沒有這個問題。
| 頁簽 | 商品(6 個) | 分類(4 個) | 座標 | 儲存通道 |
|---|---|---|---|---|
| 基本資訊 | ✓ | ✓ | 原生欄位 | WP 原生 |
| 基本資訊 地區 | ✓ | ✗ plm#19 | _product_{f}_{region} | admin-ajax |
| 基本資訊 翻譯 | ✓ | ✗ plm#19 | _product_{f}_{locale} | admin-ajax |
| 樣板設定 | ✓ | ✓ | main_en | REST |
| 樣板設定 地區 | ✓ | ✓ | {region}_en | REST |
| 樣板設定 翻譯 | ✓ | ✓ | main_{locale} | REST |
?edit_region=,不是 ?region=
兩支 JS 都明文註記原因:?region= 是前台 resolve_current_region() 的正式輸入,
帶了會種下 30 天 cookie(product-fields-manager.js:193-195、
product-region-editing.js:14)。
後台頁簽是純 JS 切換 + history.replaceState,不換頁。
v0.59.0 起是兩組一維(region 一組、locale 一組),OR 判定——命中任一即隱藏。
meta key _inwin_product_hidden_visibility,只掛在 product 上,形狀是扁平字串陣列
如 ['locale:hant', 'region:apac']。
flowchart TD
Q["前台請求"] --> BP{"should_bypass()?
cron / WP-CLI / 後台非 AJAX
/ REST / Elementor 預覽
/ VisualEditor"}
BP -->|是| SKIP["整組跳過"]
BP -->|否| SC{"場景"}
SC -->|單一商品頁| H1["template_redirect (pri 1)
get_post_meta → 判定"]
SC -->|archive / tax / search| H2["pre_get_posts (pri 10)
需 is_main_query()"]
SC -->|related / upsell
cross-sell / compare| H3["四個 WC filter
已有 id 清單"]
H1 --> J
H3 --> J
H2 --> CAND["get_hidden_product_ids()
meta_query 三條 LIKE
=候選過濾"]
CAND --> FETCH["fetch_hidden_meta_for_ids()
先問 get_post_metadata filter
回 null 才查 DB"]
FETCH --> J{"is_hidden_by_meta()
唯一判定"}
J -->|命中 region 或 locale
或舊格式降維| HIDE["隱藏"]
J -->|否| SHOW["顯示"]
HIDE -.->|單頁| R404["set_404()"]
HIDE -.->|清單| RNOT["併入 post__not_in"]
style BP fill:#fff3cd,stroke:#9a6700
style J fill:#eaf6ed,stroke:#1a7f37
style CAND fill:#f2f3f5,stroke:#999
圖 3 — 三條讀取路徑結構性共用同一個判定函式;SQL 只負責縮小候選集,不做判定。
HiddenVisibilityGate.php:313-316 是「SQL 只當候選過濾、判定一律回
is_hidden_by_meta()」的體現。曾有 review 提議「在 SQL 裡把 locale 白名單再寫一遍」以省掉後過濾——
已被否決。理由是那會讓判定邏輯出現第二份實作,而兩份必然漂移。
| # | hook | pri | 攔什麼 | 手法 |
|---|---|---|---|---|
| 1 | template_redirect | 1 | 商品單頁 | set_404(),不 wp_die() |
| 2 | pre_get_posts | 10 | archive/product_cat/product_tag/搜尋 | 併入 post__not_in |
| 3–4 | woocommerce_product_get_related 等 | 10 | 相關商品 | 移除 id |
| 5 | ..._get_upsell_ids | 10 | Upsell | 移除 id |
| 6 | ..._get_cross_sell_ids | 10 | Cross-sell | 移除 id |
| 7 | inwin_product_compare_visible_ids | 10 | 產品比較 | 結構上永遠 no-op(見 §4) |
| 8 | save_post_product | 99 | — | 遞增 cache version |
以下每一條都是結構性的——不是還沒寫,是現在的架構下寫不到。 依「客戶看得見的程度」排序。
| 類型 ① raw SQL | 類型 ② 次要查詢 | |
|---|---|---|
| 誰 | atelement-widgets 的 megamenu | Elementor Pro 的 loop widget(跑在我們自己的 iLayout/樣板裡) |
| 機制 | 直接 $wpdb->get_results(),根本不經過 WP query 層 | 正常的 WP_Query,pre_get_posts 有跑 |
| 為什麼沒生效 | 沒有任何 hook 可掛 | 我們自己要求 is_main_query() 而主動放行 |
| 影響面 | 站台 Header megamenu | Series 頁、三條產品線的 Main 頁 |
| 誰能修 | 需要前端配合改 widget | 我們自己這邊就能修 |
⚠️ 這兩類很容易被混為一談。實測顯示客戶看得到的漏出,大宗是類型 ②,不是 ①—— 而類型 ② 完全在我們自己的控制範圍內。
flowchart LR
subgraph BE["at-inwin-plugin(後端)"]
HOOKS["hook 層
pre_get_posts / template_redirect
get_terms_args / WC filters"]
end
subgraph FE["atelement-widgets(前端 · Lilith)"]
RAW1["query_child_terms_en_raw()
raw SQL"]
RAW2["get_en_term_raw()
raw SQL"]
RAW3["get_ipc_products_by_subcat()
raw SQL"]
TM["get_term_meta()
✅ 仍走 WP API"]
end
HOOKS -.->|❌ 攔不到| RAW1
HOOKS -.->|❌ 攔不到| RAW2
HOOKS -.->|❌ 攔不到| RAW3
HOOKS ==>|✅ 唯一接觸點| TM
RAW1 --> MENU["站台 Header megamenu
全站每頁"]
RAW2 --> MENU
RAW3 --> MENU
TM --> MENU
style RAW1 fill:#fdf0f0,stroke:#8b1d1d
style RAW2 fill:#fdf0f0,stroke:#8b1d1d
style RAW3 fill:#fdf0f0,stroke:#8b1d1d
style TM fill:#eaf6ed,stroke:#1a7f37
圖 4 — 前端的四個資料接觸點,只有 get_term_meta() 那一條攔得到。
IPC 第 3 欄的商品清單走 raw SQL(at-main-menu.php:906-960),
篩選條件只有 post_type='product' AND post_status='publish'。
後端的兩個執行點(template_redirect 單頁 404、pre_get_posts archive 排除)
都攔不到這條查詢。
⇒ 當前地區/語系下應被隱藏的商品,仍會出現在選單裡並帶著可點的連結,點進去才被 404。
前端的程式碼註解已知悉此事(at-main-menu.php:901),但沒有任何補償措施。
順帶:WooCommerce 自己的 exclude-from-catalog 也一併失效。
這是一條環環相扣的死路:
should_bypass() 在 REST_REQUEST 時回 true(HiddenVisibilityGate.php:359)filter_compare_ids() 第一行就呼叫它(:507)
⇒ inwin_product_compare_visible_ids 這個攔截點在實際使用情境下是 no-op。
這是後端要修的,列在這裡是因為它會影響「比較功能要不要跟著地區走」的討論。
HiddenVisibility 整組只掛在 product 上:metabox 註冊在 'product'、
儲存掛 save_post_product、meta key 是 post meta。分類 term 本身無法被隱藏。
分類側只有 locale 軸、沒有 region 軸。分類名稱/副標題/簡介/圖庫在
americas 與 apac 下完全相同。
但「樣板設定 地區」是有效的(走 iTemplateVariantKeys + get_term_meta)——
這個不對稱容易讓人誤判成 bug。
| 缺口 | 結構性原因 | 位置 |
|---|---|---|
| archive 的候選探索看不到 filter 改寫後的 meta |
post__not_in 必須在查詢之前算出 ⇒ 得先有候選名單 ⇒ 只能反查 postmeta 表。
而 core 的 get_metadata_raw() 是先問 filter、非 null 就不看 DB(WPML 掛的就是它)。
方向是單向的:filter 把「命中」改成「不命中」時後過濾吃的是 filter 值 ⇒ 不會比單頁多藏東西。 已用測試正面釘住。 |
Gate.php:196-216 :275-302 |
| 🔴 只有 main query 被攔 (類型 ②,站上實測已確認) |
maybe_filter_query 要求 is_main_query()。
⇒ Elementor loop 只要用自建查詢(post_query_post_type 是
product 或 related)就完全不過濾;
走 current_query 的才吃得到主查詢的排除。
related/upsell/cross-sell 是靠另外四個 WC filter 補的,不是靠這條。 sitemap 也在外:實測 Yoast 的 /product-sitemap.xml 帶不帶
?region= 完全相同(246 個 URL、byte 數一致)。 |
Gate.php:419 |
搜尋只在 post_type 明確含 product 時才攔 |
query_targets_product() 在 post_type 未設定時回 false(保守選擇)
⇒ 未帶 post_type 的站內搜尋不排除隱藏商品。 |
Gate.php:582-594 |
| 麵包屑完全在規則之外 | 站上的麵包屑是 Elementor Pro 的 breadcrumbs widget,
而它的 render() 只是 WPSEO_Breadcrumbs::breadcrumb() 的薄包裝
⇒ 內容全由 Yoast 產生。全站只有一個這種 widget(post 9587),
被 Header 引用 ⇒ 每一頁都有。
⇒ 隱藏規則沒有掛 Yoast 的 filter,就管不到麵包屑。 |
elementor-pro/.../breadcrumbs.php |
| 只涵蓋 product_cat / product_tag | product_brand、屬性 pa_* 的 archive 不在範圍。 |
Gate.php:422-424 |
cache 失效只綁 save_post_product |
REST 寫入、WP-CLI、update_post_meta() 直呼、遷移腳本都不會讓 archive 的 hidden id 清單失效。
另 flush_cache() 忽略 wp_cache_set() 回傳值,
且內部 get 非 forced ⇒ 讀到落後副本會把 version 寫小、讓舊快取復活。 |
Gate.php:100 :329-332 |
| 儲存只認 classic metabox 表單 | 沒有 nonce 就 return ⇒ block editor、REST、WC 批次匯入寫不到也刪不掉這個 meta。 檔內承認並視為對稱限制。 | HiddenVisibility.php:47-52 |
| 缺口 | 說明 | 位置 |
|---|---|---|
| 三個 raw SQL 讓所有 term filter 落空 | 後端若把分類隱藏實作成 get_terms_args / terms_clauses / pre_get_terms / get_term
上的 filter(這是最自然的 WP 作法),前端一條都收不到。
⇒ 只有「用 term meta 表達的隱藏規則」擋得住這個選單。 |
at-main-menu.php :1200-1211 :1249-1278 |
| 地區切換不重新載入 | 地區欄的 <a href="#"> 沒有 preventDefault(),點擊只寫 cookie + 跳錨點。
⇒ 當前頁的後端渲染內容仍是舊地區,要到下一次導覽才對齊。 |
at-main-menu.js:217-220 |
| megamenu 的地區其實不影響內容 | get_bm_categories_for_region() 收 $region_slug 但函式體完全忽略它,
同一份 JSON 原樣複製到四個地區。註解自陳「Phase 4 靜態版…Phase 7 時替換」。
⇒ 地區在前端目前只是一個寫 cookie 的 UI。 |
at-main-menu.php:827-832 |
| 手機版永遠不會設定地區 | mobile accordion 底下沒有地區層 ⇒ _currentRegionSlug 保持 null ⇒ 不寫 cookie
⇒ 後端維持 main=不做地區隱藏。這是刻意設計,但後果是手機流量全部落在 main。 |
at-main-menu.php:577-636 |
| BM 的連結永遠是 EN URL | $localize_url = false ⇒ BM 所有連結不帶語系前綴。
⇒ 從 BM 選單進入的流量,locale 維度被固定成 en。 |
at-main-menu.php:831 |
show_in_menu 現在可讀不可寫 |
前台仍在讀並據以隱藏分類,但後台 UI 被 SHOW_IN_MENU_UI = false 關掉。
⇒ DB 裡殘留的 '0' 會永久隱藏該分類整棵子樹且無法從後台修復。
關閉原因寫的是「後台 metabox 的職責範圍尚未與後端確認」——那個後端就是我們。 |
class-menu-category-metabox.php:34 |
以上都是「機制上會怎樣」。這一節是站上實際有多少—— 資料來自 mlab 本機站(2026-07-29 正式站快照),登入狀態實測。
woocommerce_coming_soon = yes)⇒ 未登入的 curl 打任何商品/分類頁,
內容區全部被換成 coming-soon 區塊,會量到「0 個商品」的假象。所有前台實測必須帶登入 cookie。id="query-monitor 之後才數。| 分群 | 分類數 | 商品計數 | 隱藏規則生效? |
|---|---|---|---|
| 兩者皆無 ⇒ 原生 WooCommerce archive loop | 52 | 334 | ✅ 實測生效 |
| 只有 Elementor archive 樣板 loop-grid + current_query | 23 | 457 | 推論生效 未實測(見下) |
只有 itemplate_id(iLayout)⇒ Series 頁 | 25 | 94 | ❌ 實測漏出 |
| 兩者都有(Elementor 那支是 draft ⇒ 實走 iLayout) | 1 | 2 | ❌ |
另外 378/389/390 三條產品線的 Main 頁雖然有 Elementor archive 樣板,
但主體是 loop-carousel 且用自建查詢(post_query_post_type: product)
⇒ 同樣漏出。
C583(post 36746,["locale:hant","region:emea"])與 EA065(["region:apac"])
是全站僅有的兩筆隱藏設定。數字=該商品連結在 HTML 中出現的次數:
| 分類頁 | 渲染路徑 | plain | ?region=emea | ?region=apac |
|---|---|---|---|---|
| 379 b-case | 原生 Woo loop | c583=2 | 0 ✅ | 2 |
| 380 b-c-atx | 原生 Woo loop | c583=2 / ea065=2 | c583=0 ✅ | ea065=0 ✅ |
| 381 b-c-atx-c(C Series) | iLayout | c583=1 | c583=1 ❌ | 1 |
| 378 models-business | loop-carousel 自建查詢 | c583=1 / ea065=1 | c583=1 ❌ | ea065=1 ❌ |
| 商品單頁 | single | 200 | 404 ✅ | 200 |
漏出來的是貨真價實的商品卡片(e-loop-item-36746、帶可點連結),不是 schema 殘留。
渲染它的是 BM_CASE_series_list(post 18072)的 loop-carousel,
查詢為 post_query_post_type: related。
current_query)是否被過濾,沒有直接證據。
站上兩個有隱藏設定的商品都不在任何 ProdFilter-* 覆蓋的分類裡。
「它吃主查詢」是從「只渲染主查詢第一頁 16 筆」推論的。/zh-hant/models-business/c583/ → 404)。pagination_type 是
load_more_infinite_scroll ⇒ 第 2 頁以後由 AJAX 取得,那條路徑是否套用隱藏未驗證。| 項目 | 筆數 | 意義 |
|---|---|---|
_inwin_product_hidden_visibility(post meta) | 2 | 全站只有 C583、EA065 |
wp_termmeta 中 %inwin%/%hidden%/%region% | 0 | 分類層完全沒有隱藏資料(plm#11 是從零開始) |
itemplate_data_* 的非 main_en 座標 | post meta 1 term meta 1 | 地區/語系座標幾乎沒被用過 |
| 商品語系翻譯 meta | _product_title_hant 2_product_title_japn 1 | 翻譯資料極少 |
| megamenu 四個地區區塊的分類樹 | 四份 JSON 完全相同(各 44 節點、md5 一致)⇒ 實證了「地區不影響選單內容」 | |
get_terms()——Elementor 的 get_settings_for_display()
會觸發 register_controls(),連帶執行編輯器面板的分類下拉查詢
(at-main-menu.php:121)。它不影響選單輸出,
但意味著任何掛在 get_terms_args 上的邏輯,每頁都會被觸發一次。pt-pt 這種語言時,
locale:pt-pt 這個隱藏 entry 永遠存不進去也判不出來(該語系無法被隱藏)。Header_business(10294)的三條條件
全部指向 category/11,而 term 11 不存在 ⇒ 這支 header 永遠不會套用。
ProdFilter-IPC-Accessory(77028)同理(term 393 已刪)。
連帶 Header_default_1 的三條 exclude 也永遠不成立 ⇒ 它是真正的無條件全站 header。iTemplateModel(712 行)是死碼——production 零呼叫者,
唯一的 require_once 已被註解掉。但 iTemplateVariantKeys 的 docblock 仍把它列為三處 reader 之一。現況:地區切換只寫 cookie、不重載,而且前端的 megamenu 內容根本不隨地區變化
(get_bm_categories_for_region() 忽略參數)。後端則沒有任何前台切換 UI。
要決定的:
main。docs/CURRENT.md 寫「地區相關的開發一律由後端負責」,
但實際上 cookie 的寫入點在 megamenu 的 JS 裡,而後端沒有任何前台切換 UI。
兩邊的認知在這裡有落差,先對齊再動工。商品側已完成(v0.59.0 兩組一維),但有三個已上線的破口, 其中兩個在我們自己這邊:
is_main_query() 把它們放行了。
這是 C583 客訴的真正成因,不是前端的問題。分類側(plm#11)尚未開始,而這份圖給出一個硬約束:
分類隱藏必須用 term meta 表達,不能只靠 get_terms_args 之類的 filter。
因為前端 megamenu 走 raw SQL,唯一還會經過 WP API 的接觸點是 get_term_meta()。
選錯實作方式的話,後台設了隱藏、選單照樣列出來。
這也重新框定了 C2(全域 get_terms_args 過濾)的取捨:它涵蓋不到 megamenu 這件事已確認,
而且它每頁都會被 Elementor 的面板查詢觸發一次——正好落在它卡了四輪的 re-entrancy 問題上。
三個已知的不對稱,動之前要先確認哪些是刻意的:
另外前端有兩個對後端 key 的硬編碼假設:_product_title_{locale}(商品名)
與 \inwin_template_plugin\Module\iTemplate\iTemplateRenderer::resolve_current_locale()(完整命名空間寫死)。
後端改了任一個都不會報錯,只會靜默退回英文。
docs/main_menu/後端-商品區域隱藏-整合參考.md 建立於 2026-07-03、基於 v0.38.1,
記的是「region:locale 二維」模型;v0.59.0 起已改成兩組一維
(region 一組、locale 一組,OR 判定)。照舊文件做整合會對不上,這份圖的 §3 是現行版本。get_term_meta() 是唯一還走 WP API 的接觸點。
你在整合參考裡問的三個問題(meta key/格式/掛在哪一層),我們會在規格裡正式定義後給你。
如果 term meta 的形狀有你這邊偏好的樣子,這時候提最省事。SHOW_IN_MENU_UI 的職責範圍。
你註記的「等後端確認 metabox 職責範圍」——這題該我們回答。
在回答之前不會動 show_in_menu,避免做出語義重疊的第二套開關。
資料來源:at-inwin-plugin v0.60.0 與 atelement-widgets v3.15.4 的原始碼逐行核對(2026-09-02)。
站上資料引用自 mlab 本機站,該站是 2026-07-29 正式站快照,之後的異動無從得知。
本頁供 InWin 專案前後端共同參考。推論與實測已分別標示;有出入之處請直接指正。