在地化
本頁包含介面文字的來源、哪些不翻、語言切換與遷移流程;固定譯名與英文文風見 術語表。
文字從哪裡來
- 使用者看得到的文字一律寫在
<類別>.<語言>.resjson,與用它的程式碼放同一個資料夾。zh-Hant是來源語言,決定有哪些鍵與佔位符;檔案是扁平的「鍵 → 文字」,可寫//註解給譯者。 tools/SqlAssist.TextGenerator產生同名的 public static class,命名空間由src/<專案>/<資料夾>推出。沒有佔位符的是屬性,有的是方法:UpdateText.Available(latest, current)。- 佔位符一律具名(
{count}、{size:N0}),譯文可以調換語序;不收{0}。英文單複數用句型避開, 避不開就拆兩個鍵,不在程式裡拼字尾,也不拿數字接量詞({count} 個整句翻)。 - 數字依介面語言格式化:句子裡的寫成佔位符格式,不在句子裡的(統計格、徽章)用
SqlText.Number; 不用CultureInfo.CurrentCulture,那是 SSMS 的文化,可以與介面語言不同。 - 各語言的鍵、佔位符不一致、缺檔,或非中日韓語言的譯文含中日韓字元(漏翻),都是建置錯誤 (SQLTXT001–011),不在執行期退回來源語言。
- 不用 resx:衛星組件要靠 VSIX 探測路徑與隔離 AppDomain 各自載入,載不到只會安靜退回; 產生器把所有語言編進同一個組件,參數個數也由編譯器檢查。
- 唯一例外是設定頁:註冊檔只能寫
@鍵;{packageGuid},由 SSMS 到套件組件的資源查表。文字照樣寫在Ssms22/Settings/SettingsPageText.<語言>.resjson、照同一流程翻譯;檔案標SqlAssistTextResourceOnly, 產生器照同一套 SQLTXT 規則驗證但不產生類別。SettingsPageText.targets在建置時把英文編成中性資源 、其餘語言編成衛星組件(在 Deploy 白名單裡,缺了只會安靜退回英文);引用不存在的鍵是 SQLSET006。 - 中性語言一律是英文:設定頁資源、命令表(
Menus.vsct)與 vsixmanifest 都寫英文,繁中分別走衛星組件、TextChanges與zh-Hant/Extension.vsixlangpack。 - 語言清單只有根目錄
Directory.Build.props的SqlAssistTextLanguages一份(逗號分隔)。 新增語言:加在那裡、每份.resjson與資料型覆蓋檔補一份、語言設定加一個列舉值。 - 跨功能的共用詞(確定、取消、複製)放
Core/Localization/CommonText;SQL 物件與建議項目的種類名稱 (資料表、預存程序、資料表提示……,含複數形)放同一資料夾的SqlKindText。不在各功能各翻一次。
資料型文字
Keywords/BuiltInDocs/*.json、DefaultSnippets.json這種一筆多欄、帶巢狀表的內嵌資源不進產生器:來源維持繁中, 旁邊放同名覆蓋檔<名稱>.<語言>.json,由Core/Localization/SqlTextOverlay依語言疊上去,缺的欄位用來源那一句。格式是
{ "<編號>": { "<欄位>": "譯文" } },只放含中文的文字欄;編號與欄位由載入器定,陣列位置從 0 起算:來源 編號 欄位 BuiltInDocs/的各種類檔namesummary、examples.<範例 id>.title/.sql、references.<位置>.title/.columns.<欄>/.rows.<列>.<欄>(只限內嵌表)BuiltInDocs/tables.json表格編號 title、columns.<欄>、rows.<列>.<欄>DefaultSnippetsidtitle、description、code、placeholders.<欄位 id>.tooltip/.default範例與片段樣板只翻
--註解與中文字串常值,$surround$、{name}原樣保留。覆蓋檔內嵌時標
WithCulture="false",否則 MSBuild 把.en.json當文化資源拆進衛星組件。關鍵字目錄(
SqlDataTypeCatalog這幾個.cs)的一行說明走.resjson而不是覆蓋檔:覆蓋檔要把中文來源留成 字面值(SQLTXT100 擋),.resjson的鍵由編譯器檢查。目錄存() => DataTypeText.Int,取值時才讀語言。提示視窗的截斷上限以字元計、不分語言,英文照同一個上限寫得精簡。 不改成依顯示寬度截斷:同一條路徑也截使用者的擴充屬性說明,放寬會連它一起放寬。
什麼不翻
- 診斷紀錄、平台防護的作業名稱與診斷報告:給維護者比對,固定繁中。在接收的參數或所在成員 標 BCL 的
[Localizable(false)](CA1303 同一套語意),SQLTXT100 就不檢查。 - 使用者資料(SQL Memory、收藏、自訂片段)與 SQL Server 回傳的訊息。未命名查詢視窗的預設文件名稱照擷取當下的 語言存進
Documents.DisplayName:查詢視窗一定帶標題,這條幾乎走不到,不值得為它改存代碼。 - 設定鍵、moniker、列舉字面值與儲存格式。
- 已經寫進編輯器的文字不回頭改;之後產生的指令碼註解用當下的語言。
目前語言
- 取值走
Core/Localization/SqlText.Current。不動Thread.CurrentUICulture:那是 SSMS 的狀態。 - 設定
sqlAssist.general.language(auto/zhHant/en,字面值是語言名稱去掉連字號)。auto由SqlLanguage.Match依宿主介面文化挑:zh-* 用繁中,其餘用英文。宿主文化只在 UI 執行緒問得到 (IUIHostLocale),Ssms22/Settings/SqlLanguageSwitch在設定接上時問一次記下來。 - 設定生效前是來源語言,所以既有測試的中文斷言不必改。固定語言用
SqlText.Use(...)(AsyncLocal,平行測試互不干擾);會切換全域語言的測試放進不平行的集合。 - 隔離 AppDomain(SQL Memory 儲存)有自己一份
SqlText.Current,不跟著宿主切換。隔離側只回分類、原因碼與 錯誤碼,例外訊息當診斷;給使用者的句子由宿主的SqlMemoryTimeText.Describe組。
即時切換
設定變更時 SqlAssistSettingsStore.Reload 呼叫 SqlText.SetLanguage。SqlText.Changed 在呼叫端的執行緒上發出; 介面改接 SqlLanguageSwitch.Changed:保證在 UI 執行緒、每個處理常式各自走 Guard,訂閱者關閉時要解除訂閱。
| 表面 | 切換後 |
|---|---|
| 每次才產生的文字(補全、提示、通知、指令碼) | 下一次就是新語言 |
| 含譯文的快取與不可變物件(圖示朗讀名稱) | 以語言為鍵各留一份(SqlLanguageCache):平台以實體比對,不能每次新建 |
| 載入時合併的資料(內建片段) | 記著合併時的語言,不同就重新合併 |
| 工具窗(SQL Search、SQL Memory) | 整份內容重建,帶著搜尋字串與分頁;建構時取字的元件一起換 |
| 浮動結構預覽 | 關掉並丟掉建好的視窗,下次展開重建 |
| 區塊摺疊提示、邊欄說明、跨頁提示 | 丟掉快取重發 TagsChanged;跨頁提示忘掉顯示過的那一組 |
| 已顯示的通知 | 重新投影:標題、狀態與按鈕換;各功能建立時組好的訊息留在舊語言直到到期 |
| 選單命令 | 命令表每顆標 TextChanges,QueryStatus 設 Text;Test-CommandTable.ps1 核對 |
字型與色彩的分類名稱(ClassificationFormatDefinition) | MEF 建立時定字,重新啟動 SSMS 才換 |
| 強制回應對話框 | 開著時進不了設定,不處理 |
| 設定頁、擴充功能清單、鍵盤頁的命令名稱 | 跟隨 SSMS 介面語言,本設定管不到;命令名稱(LocCanonicalName)只有英文 |
新增介面文字
SQLTXT100 全面開著,沒有暫時豁免的資料夾。
- 先查
CommonText/SqlKindText有沒有同一句;沒有才在用它的資料夾找現有的<類別>.zh-Hant.resjson,再沒有才新增一組。 - 建置那個專案。SQLTXT100 列出的檔案、行號與前 24 字就是漏網的字面值,只讀命中行附近。 Core、Metadata、Sqlite 用
dotnet build src/<專案> -c Release;Ssms22 走tools/Build-Extension.ps1。 - 文字寫進
<類別>.zh-Hant.resjson(鍵用 PascalCase),呼叫端改用產生的成員,拼接字串改成 一整句具名佔位符;只進紀錄的改標[Localizable(false)](見「什麼不翻」)。 - 翻譯交給
.claude/agents/resjson-translator.md:一個區塊只呼叫一次, 只傳全部 zh-Hant 檔路徑;回來只審譯文。沒有這個代理的工具照術語表手動翻。 - 建置+測試;每個區塊至少補一個
SqlText.Use英文斷言。建構時就取字的介面元件要照「即時切換」那張表接上。