08.08.2026 –, TR409-2
我和北科程式設計研究社的伙伴利用課餘(以及偶爾的上課時間)維護一款 GPLv3 授權的校園軟體 Tattoo,協助北科大學生查課表、看成績、處理校務系統。專案從 zh-TW 與 en-US 雙語起步,英文由社團成員人工翻譯;後來為了服務校內多數來自非英語系國家的外籍生,又逐步擴充到我們自己不熟的語言,採用「LLM 出初稿、再透過翻譯平臺交給該語系學生修正」的流程。半年下來繞了不少遠路,這場分享想把走過的路攤開,給做小型自由軟體本地化的開發者一份參考。
一開始談翻譯協作平臺。為了上述的多語流程,我先後試過 Weblate 和 Crowdin,最後兩個都關掉了。一方面是同步機制本身彆扭:譯者在平臺上的修改會被 bot 一筆筆推回 GitHub,被「New translations zh-tw.i18n.yaml」這類 commit 淹沒主線。另一方面是兩個平臺接 GitHub 的權限模型:為了一個專案的翻譯,卻得授權整個組織的管理權限,這個取捨很難說服自己。最後我們只能暫時關閉同步,並重新思考要怎麼讓非開發者的譯者貢獻。
我們還會介紹 Flutter 上的選擇。Flutter 生態有幾套常見的 i18n 套件,我們最後選了對譯者與審查者格式友善的 slang。框架本身不是這場的重點,只會用幾分鐘帶過技術選型的過程。
接下來我們會討論翻譯檔的儲存格式。從 ARB (JSON-based) 看到 JSON、YAML,討論為什麼落腳在 YAML:人類可讀、可註解、多行字串友善、不被尾逗號搞死。當然 YAML 並非完美方案:行尾多餘空格、長字串折行語意、保留字與特殊字元的 escaping 都會偶爾造成問題,這些經驗一併分享。
最後是漢英對譯實戰陷阱:以漢語為母語的開發者很容易忘了其他語系有單複數、時態等語法分支——當你直覺地把字串寫好後,等到 en-US 要區分 one/other 時,就得回頭重寫整個結構,整個 App 一起改。我會以「密碼將於 N 天後過期」為例,示範從第一天就該怎麼設計翻譯鍵。同場加映 CJK 與英數字之間的空格該不該寫進原始字串、教室名稱與專有名詞的雙語對應策略,以及校務系統回傳混雜中英資料時,如何用一個小小的 localized(zh, en) helper 處理。
希望這 30 分鐘能讓做 Flutter App 或其他軟體的朋友,少踩幾個我們踩過的坑。
我會在稍後補上,造成不便敬請見諒。
TBD