本项目已实现完整的多语言支持,使用 Windows 资源文件 (.resw) 来存储本地化字符串。
BitwardenForCommandPalette/
├── Strings/
│ ├── en-US/
│ │ └── Resources.resw # 英文资源
│ ├── zh-CN/
│ │ └── Resources.resw # 中文资源
│ ├── ja-JP/
│ │ └── Resources.resw # 日文资源
│ ├── ko-KR/
│ │ └── Resources.resw # 韩文资源
│ ├── fr-FR/
│ │ └── Resources.resw # 法文资源
│ └── es-ES/
│ └── Resources.resw # 西班牙文资源
└── Helpers/
└── ResourceHelper.cs # 资源访问辅助类
目前支持的语言:
- en-US: 英语(美国)- 默认语言
- zh-CN: 简体中文
- ja-JP: 日语
- ko-KR: 韩语
- fr-FR: 法语
- es-ES: 西班牙语
在 Strings/ 目录下创建新的语言代码文件夹,例如:
ja-JP- 日语fr-FR- 法语de-DE- 德语es-ES- 西班牙语
将 Strings/en-US/Resources.resw 复制到新的语言文件夹中:
Copy-Item "Strings/en-US/Resources.resw" "Strings/ja-JP/Resources.resw"打开新的 Resources.resw 文件,翻译 <value> 标签中的内容:
英文版本:
<data name="CommandCopyPassword" xml:space="preserve">
<value>Copy Password</value>
</data>翻译后 (日语示例):
<data name="CommandCopyPassword" xml:space="preserve">
<value>パスワードをコピー</value>
</data>重要:
- 不要修改
name属性 - 不要修改包含
{0},{1}等占位符的位置或顺序 - 仅替换
<value>内容,保持 XML 结构、注释、空白行与属性顺序完全一致 - 对
&,<,>等字符进行 XML 转义,避免破坏文件结构
在提交前确保所有语言的键集合一致,并抽样确认翻译是否正确写入:
python - <<'PY'
from __future__ import annotations
import re
from pathlib import Path
def keys(path: Path) -> list[str]:
return re.findall(r'<data name="([^"]+)"', path.read_text(encoding="utf-8"))
root = Path("Strings")
en_keys = keys(root / "en-US" / "Resources.resw")
for lang_dir in sorted(p for p in root.iterdir() if p.is_dir() and p.name != "en-US"):
lang_keys = keys(lang_dir / "Resources.resw")
print(lang_dir.name, "keys match:", en_keys == lang_keys)
PY- 在 Windows 设置中将系统语言更改为目标语言
- 重新部署扩展
- 启动 Command Palette,检查翻译是否正确显示
| 类别 | 前缀 | 说明 | 示例 |
|---|---|---|---|
| 应用程序 | App |
应用名称等 | AppDisplayName |
| 操作 | Action |
通用操作 | ActionOpen, ActionUnlock |
| 命令 | Command |
用户命令 | CommandCopyPassword |
| Toast | Toast |
提示消息 | ToastPasswordCopied |
| 页面 | *Page* |
页面相关 | UnlockPageTitle |
| 筛选 | Filter |
筛选选项 | FilterAllItems |
| 状态 | Status |
状态消息 | StatusLoading |
| 主页面 | Main |
主界面 | MainPageTitle |
| 项目 | Item |
项目显示 | ItemSubtitleSecureNote |
某些资源字符串包含格式占位符:
<!-- 单个占位符 -->
<data name="ToastFieldCopied" xml:space="preserve">
<value>{0} copied</value>
</data>
<!-- 使用示例 -->
ResourceHelper.ToastFieldCopied("Email") // 输出: "Email copied"using BitwardenForCommandPalette.Helpers;
// 获取简单字符串
var title = ResourceHelper.AppDisplayName;
var buttonText = ResourceHelper.CommandCopyPassword;// 带参数的字符串
var message = ResourceHelper.ToastFieldCopied("Email");
var filterDesc = ResourceHelper.FilterDescFolder("Work");// 直接通过键访问
var text = ResourceHelper.GetString("CommandCopyPassword");
// 带格式化参数
var formatted = ResourceHelper.GetString("ToastFieldCopied", fieldName);public MyCommand()
{
Name = ResourceHelper.CommandMyAction;
Icon = new IconInfo("\uE8C8");
}
public override CommandResult Invoke()
{
// ... 操作逻辑
return CommandResult.ShowToast(ResourceHelper.ToastActionCompleted);
}public MyPage()
{
Title = ResourceHelper.MyPageTitle;
Name = ResourceHelper.ActionOpen;
PlaceholderText = ResourceHelper.MyPagePlaceholder;
}使用字符串插值将资源嵌入 JSON:
TemplateJson = $$"""
{
"type": "TextBlock",
"text": "{{ResourceHelper.UnlockCardTitle}}"
}
""";- 使用清晰的命名约定
- 为相关的字符串使用相同的前缀
- 保持命名的语义化
❌ 错误:
Title = "Copy Password";✅ 正确:
Title = ResourceHelper.CommandCopyPassword;不同语言的文本长度可能差异很大:
- 中文通常比英文短
- 德语通常比英文长
- 设计 UI 时预留足够空间
某些语言可能需要调整占位符顺序:
<!-- 英文 -->
<value>Copy {0} to clipboard</value>
<!-- 日语(可能需要不同顺序) -->
<value>{0}をクリップボードにコピー</value>- 避免使用特定文化的习语或俚语
- 注意日期、时间、数字格式
- 考虑不同的文化习惯
在添加新语言后,测试以下内容:
- 所有菜单项和按钮标签正确显示
- Toast 消息正确显示
- 页面标题和占位符文本正确
- 筛选选项标签正确
- 状态消息正确
- 错误消息清晰易懂
- Adaptive Card 表单正确显示
- 长文本不会导致 UI 布局问题
- 格式化字符串的参数正确替换
- 确认 .resw 文件位于正确的文件夹
- 检查文件编码是否为 UTF-8
- 确保 .csproj 中包含
<PRIResource Include="Strings\**\*.resw" /> - 清理并重新构建项目
- 检查文件夹名称是否与 Windows 语言代码完全匹配
- 确认所有键都已正确翻译
- 验证 XML 格式没有错误
- 确保占位符
{0},{1}等在所有语言中存在 - 检查
ResourceHelper.GetString()调用中的参数数量 - 使用
CultureInfo.CurrentCulture进行格式化
如果您想为项目贡献新的语言翻译:
- Fork 项目
- 创建新的语言文件夹和 Resources.resw
- 完成翻译
- 测试翻译质量
- 提交 Pull Request
感谢您为项目的多语言支持做出贡献!