9月27日
食譜卡不用重抄一遍,你在旁邊加一行眉批就夠了
一篇關於管理後臺國際化不建翻譯表、只在 JSON 欄位加一個鍵的技術文章,被我們翻譯成廚房裡食譜卡邊上的眉批與一鍋湯的預設味道。
2026 年 9 月 24 日,開發者 mldong 在掘金發了一篇文章,談管理後臺的資料國際化:選單名稱、字典標籤、公告標題這些存在資料庫裡的文字,要怎麼支援多語言。他的結論很乾脆:不建翻譯表,也不每種語言加一列,而是在既有的 JSON 擴充欄位裡,多塞一個 i18n 鍵。
這聽起來離廚房很遠。但你先想想家裡那張用了很多年的食譜卡。
卡上是媽媽的字,寫著「紅燒牛肉,豆瓣醬兩大匙,小火兩小時」。這是預設版本,是這張卡的「主欄位」。後來你想做給不喫辣的朋友喫,你沒有另外抄一整張新卡,只是在旁邊用鉛筆加了一行:不加豆瓣,改醬油加番茄半顆。再後來朋友的女兒來喫飯,你又補一行:糖多一點,孩子愛。
一張卡,主配方照舊,幾行眉批掛在邊上。這正是那篇文章的做法:主欄位存預設語言,其他語言的譯文收進同一列 JSON 裡的一個 i18n 鍵,要支援日文,就往裡面多加一個鍵,表結構完全不用動。
文章裡算了另外兩種做法的帳,放在廚房裡也說得通。
第一種是建一張翻譯表,任何表、任何欄位、任意多語言都裝得下,能力最強。這就像替每一道菜另開一本翻譯筆記本,所有調整都記在筆記本裡,原卡保持乾淨。做一桌幾十道菜、還要交給外面師傅統一調味的餐廳,這樣做是對的。但家裡三、五道菜也這樣搞,每次下廚都得先翻筆記本核對一次,原卡上刪了一道菜,筆記本裡那幾頁還留著,成了孤兒資料。
第二種是每種語言加一列,查詢最快,譯文就在行內。這等於替「不辣版」「小孩版」「減鹽版」各抄一張完整的卡。卡是清楚了,可是哪天想加一個「低醣版」,三張卡全得重抄一遍,語言集合就這樣被焊死在卡片結構裡。
第三種的帳,文章算得明白:加語言變成資料操作,一行更新就完事;讀取時譯文跟著原本那筆資料一起帶出來,沒有第二次查詢;沒有 i18n 鍵的舊資料,讀取時自動回退主欄位原值,行為跟升級前完全一樣;「沒有譯文就用預設值」這個判斷,全系統只寫在一個工具函式裡,一份就好。
回頭看你的食譜卡,道理一模一樣。鉛筆眉批的好處在於:哪一行忘了寫,菜還是照原味出來,鍋裡不會多出莫名其妙的空白;哪天想再加一種版本,鉛筆再補一行就是,卡不用重抄。壞處當然也有,眉批的字進不了目錄檢索,你想找「哪張卡提過減鹽」,只能一張張翻。不過食譜卡的用途本來是照著做,檢索需求本來就少,這筆交換是劃算的。
這也跟我們之前聊過的食譜卡與固定格式答案是同一門功夫:把變動的東西收進欄位,把不變的骨架留在卡上。
所以下一次你在廚房裡為「要不要另抄一張卡」猶豫的時候,可以先問一句:這個調整,值得佔一張新卡嗎?還是鉛筆一行,卡照舊,湯照燉。多數時候,答案是一行眉批。