Brackets 多语言本地化指南:从新增语言到维护翻译的完整流程(基于 src/nls/README.md)
【免费下载链接】bracketsAn open source code editor for the web, written in JavaScript, HTML and CSS.项目地址: https://gitcode.com/gh_mirrors/br/brackets
Brackets 是一款用 JavaScript、HTML 和 CSS 编写的开源 Web 代码编辑器,其用户界面文本通过src/nls目录下的国际化(i18n)体系管理。本文以 src/nls/README.md 为骨架,结合仓库内真实的 strings 配置、urls 映射、require.js i18n 插件加载机制以及各语言示例,完整讲解如何在 Brackets 中为一种全新语言新增翻译、如何修改已有翻译,以及翻译过程中必须注意的边界与限制。读完本文,你将掌握从创建语言目录、注册 locale、翻译 strings.js、翻译 "Getting Started" 示例项目,到通过 Pull Request 贡献翻译的端到端流程。
一、Brackets 本地化架构概览
在动手翻译之前,先理解 Brackets 的本地化是如何运转的,这有助于你正确放置文件。
- nls 目录:所有翻译资源都位于 src/nls 下,每种语言一个子目录(如
fr、de、zh-cn),加上一个root目录作为英文源语言。 - require.js i18n 插件:Brackets 使用 require.js i18n 插件 提供本地化能力。插件会根据当前 locale 动态加载对应语言的字符串模块。
- 入口文件:src/strings.js 是面向应用代码的加载入口,代码通过
require("strings")取用界面字符串。其内部逻辑(src/strings.js)实际执行:
var strings = require("i18n!nls/strings"), urls = require("i18n!nls/urls"), stringsApp = require("i18n!nls/strings-app"), StringUtils = require("utils/StringUtils");它同时加载nls/strings(界面文案)、nls/urls(链接与示例项目路径)、nls/strings-app(产品级字符串,如应用名),并把{APP_NAME}、{VERSION}等占位符替换为brackets.metadata中的真实值。也就是说,一套语言翻译实际上由strings.js + urls.js + strings-app.js三个模块共同组成。
- locale 注册表:src/nls/strings.js 中的
module.exports对象列出了所有受支持的语言前缀(locale prefix),这是 require.js i18n 插件识别可用语言的“白名单”。
module.exports = { root: true, "bg": true, "cs": true, "da": true, "de": true, "el": true, "en-gb": true, "es": true, "fa-ir": true, "fi": true, "fr": true, "gl": true, "hr": true, "hu": true, "id": true, "it": true, "ja": true, "ko": true, "lv": true, "nb": true, "nl": true, "pl": true, "pt-br": true, "pt-pt": true, "ro": true, "ru": true, "sk": true, "sr": true, "sv": true, "tr": true, "uk": true, "zh-cn": true, "zh-tw": true };- 界面语言切换:src/nls/root/strings-app.js 为每种语言定义了一个
LOCALE_*条目(例如"LOCALE_ZH_CN": "简体中文"),这些条目会显示在Debug > Switch Language菜单中,供用户随时切换界面语言。src/utils/LocalizationUtils.js 中的getLocalizedLabel()会依据"LOCALE_" + locale.toUpperCase().replace("-", "_")的规则(如zh-cn→LOCALE_ZH_CN)查找语言的自称。
二、为一种全新语言新增翻译(7 步完整流程)
以下步骤以nls目录下的 README 为基准,逐步拆解。
步骤 1:创建语言子目录
在nls文件夹下创建以语言或 locale 命名的子目录,命名规则有两种:
- 通用语言翻译:直接使用两位字母代码,例如
en、de。两位代码是默认形式,若你只想翻译一种语言而不区分国家/地区,就用这个。 - 特定国家/地区的 locale:在语言代码后加连字符和小写的国家代码,例如
en-ca(加拿大英语)、en-gb(英国英语)。
仓库中实际存在的例子:en-gb目录对应English (UK),pt-br(巴西葡萄牙语)与pt-pt(葡萄牙葡萄牙语)并存,说明同一语言可以按地区拆分多个翻译。
步骤 2:在nls/strings.js中注册语言
打开 src/nls/strings.js,在module.exports对象中为你的翻译添加一个条目,例如:
module.exports = { root: true, // ...已有语言... "xx": true // 新增语言,xx 换成你的语言代码 };注意root必须保持为true,它是英文源字符串所在目录的标志。漏掉这一步,i18n 插件不会识别你的语言目录。
步骤 3:在根strings-app.js中新增LOCALE_*条目
编辑 src/nls/root/strings-app.js,添加一个LOCALE_前缀条目,键名规则为LOCALE_+ 语言代码大写且连字符换成下划线,值为该语言的自称(使用该语言书写)。例如:
"LOCALE_XX" : "你的语言名称(用该语言书写)",这个条目将出现在Debug > Switch Language界面中。参照 src/nls/root/strings-app.js 中的现有写法,如"LOCALE_JA": "日本語"、"LOCALE_ZH_CN": "简体中文"、"LOCALE_FA_IR": "فارسی"。
步骤 4:复制根strings.js并开始翻译
将 src/nls/root/strings.js 复制到你的子文件夹(如src/nls/xx/strings.js),然后逐条翻译。根strings.js共约 916 行、涵盖错误提示、菜单命令、快捷键、对话框、Live Preview、扩展管理等全部界面文案;每条字符串形如:
"NOT_FOUND_ERR" : "The file/directory could not be found.", "ERROR_OPENING_FILE" : "An error occurred when trying to open the file <span class='dialog-filename'>{0}</span>. {1}",翻译时注意保留{0}、{1}这类占位符(运行时会被参数替换),以及内嵌的 HTML 标签(如<span>、<a>),只翻译其中的自然语言文本。另外{APP_NAME}、{VERSION}这类全局占位符由 src/strings.js 在运行时统一替换,不要改动。
步骤 5:在真实界面中检查字符串(UI walkthrough)
完成翻译后,使用 Localization-Tests 的 UI 走查步骤 在真实界面中逐一查看这些字符串的显示效果,确认没有截断、乱码或布局问题。这是纯静态检查无法替代的环节。
步骤 6:添加“最后翻译”注释标记
在strings.js文件末尾添加注释:
/* Last translated for commit_SHA_of_root_strings.js */并把commit_SHA_of_root_strings.js替换为你翻译所基于的src/nls/root/strings.js版本对应的实际 commit SHA。SHA 可以从该文件的提交历史页面获取。仓库中已有语言都遵循这一惯例,例如 samples/cs/Getting Started/index.html 中可见<!-- Last translated for 12ee7cd7c2c0eefb3fdee209eea92a82b66f1693 -->这样的标记。这个 SHA 是维护者的“对账依据”,用来判断翻译是否落后于英文源串。
步骤 7:更新语言列表
编辑本 README(即 src/nls/README.md)中维护的语言清单,把你新增的语言加进去,方便后续维护者知晓。
三、翻译 "Getting Started" 示例项目
Brackets 首次安装后会打开一个 "Getting Started" 示例项目,作为功能介绍页。这个项目同样可以本地化。
通过urls.js指向本地化目录
在语言目录中创建urls.js,用GETTING_STARTED键指向samples文件夹下的对应目录。urls.js中的路径是相对于 samples 文件夹的。以 src/nls/fr/urls.js 为例:
define({ // Relative to the samples folder "GETTING_STARTED" : "fr/Premiers pas", "ADOBE_THIRD_PARTY" : "http://www.adobe.com/go/thirdparty_fr/", "MDN_DOCS_LICENSE" : "http://creativecommons.org/licenses/by-sa/2.5/deed.fr" });对照仓库中 samples/fr/Premiers pas/index.html 确实存在。而 src/nls/root/urls.js 的对应值为"GETTING_STARTED": "root/Getting Started"。各种语言目录下的urls.js均采用此模式,如da/Kom godt i gang、de/Erste Schritte、uk/Pochynayemo、zh-cn/Getting Started等。
示例项目路径的运行时使用
这个GETTING_STARTED值会被项目模块消费。src/project/ProjectManager.js 中的_getWelcomeProjectPath()调用ProjectModel._getWelcomeProjectPath(Urls.GETTING_STARTED, ...)来拼接欢迎项目的完整路径,因此翻译时务必保证urls.js中的目录名与samples下实际目录完全一致,否则欢迎页会加载失败。
推荐:在示例index.html末尾也加 SHA 注释
同样建议在示例项目的index.html末尾添加:
<!-- Last translated for commit_SHA_of_root_index.html -->commit_SHA_of_root_index.html替换为你翻译所基于的根index.html的 commit SHA(即 samples/root/Getting Started/index.html)。仓库各语言的示例页确实带此类标记,例如 samples/cs/Getting Started/index.html。
一个硬性限制:目录名只能用基本英文字符
由于底层文件系统与项目加载逻辑的限制,“Getting Started” 本地化后的文件夹名只能由基本英文字符组成(正如 src/nls/README.md 所强调)。注意观察仓库中即使zh-cn、fa-ir这样的语言,其示例目录名也保持了Getting Started或Primeiros Passos、Pochynayemo这类纯拉丁字符,而不是用中文或波斯文命名。
四、如何修改已有翻译
新增翻译之外,修改已有语言同样有明确的流程约束,按维护主体分为两类。
Adobe 官方维护的语言
Adobe 官方为以下语言提供翻译:
- 法语(fr)
- 日语(ja)
这两类翻译不能通过常规 Pull Request 流程直接修改。如需贡献更改,应到仓库的 Issues 页面提交 issue 说明问题,由官方处理。
社区维护的语言
以下语言由 Brackets 社区贡献,可以直接通过常规 Pull Request 修改(截至本文,src/nls/README.md 列出的社区语言):
| 语言 | 代码 | 语言 | 代码 |
|---|---|---|---|
| Bulgarian 保加利亚语 | bg | Czech 捷克语 | cs |
| Danish 丹麦语 | da | German 德语 | de |
| Greek 希腊语 | el | Spanish 西班牙语 | es |
| Persian-Farsi 波斯语 | fa-ir | Finnish 芬兰语 | fi |
| Galician 加利西亚语 | gl | Croatian 克罗地亚语 | hr |
| Hungarian 匈牙利语 | hu | Indonesia 印尼语 | id |
| Italian 意大利语 | it | Korean 韩语 | ko |
| Latvian 拉脱维亚语 | lv | Norwegian 挪威语 | nb |
| Dutch 荷兰语 | nl | Polish 波兰语 | pl |
| Brazilian Portuguese 巴西葡萄牙语 | pt-br | Portuguese 葡萄牙语 | pt-pt |
| Romanian 罗马尼亚语 | ro | Russian 俄语 | ru |
| Slovak 斯洛伐克语 | sk | Serbian 塞尔维亚语 | sr |
| Swedish 瑞典语 | sv | Turkish 土耳其语 | tr |
| Ukrainian 乌克兰语 | uk | Simplified Chinese 简体中文 | zh-cn |
| Traditional Chinese 繁体中文 | zh-tw |
修改社区维护的翻译时,务必同时更新文件最后一行的 SHA 注释,使其与你翻译所依据的根strings.js的 commit SHA 一致;如果 SHA 注释缺失,则补上正确的 SHA(参见“新增语言”第 6 步)。另外,在这些语言仍由社区维护期间,不要使用 translate.adobe.com 进行翻译。未来 Adobe 可能接管部分语言,届时流程会切换到官方维护模式。
五、直接在 GitHub 上贡献翻译(GitHub Web 工作流)
如果你希望不克隆仓库、直接在网页端提交翻译,README 给出了完整的 Web 流程。注意本仓库是只读镜像,以下步骤描述的是上游仓库的协作规范,供参考。
5.1 添加新翻译
- 以 src/nls/root/strings.js 的内容为起点,复制全部内容。
- 在
nls文件夹页面点击 [+] 按钮新建文件,文件名为语言代码/strings.js(例如xx/strings.js)。 - 将根
strings.js内容粘贴进去,并把字符串逐条翻译成目标语言。 - 在文件末尾追加
/* Last translated for commit_SHA_of_root_strings.js */注释,SHA 从根strings.js的提交历史中复制。 - 填写简短描述(可选长描述),点击Propose New File按钮。
5.2 编辑已有翻译
- 导航到目标翻译文件,点击文件上方的Edit按钮。
- 做出所需修改。
- 同样更新文件最后一行的 SHA 注释(缺失则补上),规则见“新增语言”第 6 步。
- 填写提交说明(简短描述,可选长描述),点击Commit changes按钮。
5.3 分支与 Pull Request
无论新增还是编辑,若你尚未 fork Brackets 仓库,系统会自动在你的账号下创建 fork,并新建一个名称类似patch-1的分支承载你的改动。随后进入 New Pull Request 界面,其中已自动填好相关信息,并展示新文件内容或对已有文件的 diff。确认无误后点击Send Pull Request(或关闭页面取消)。Pull Request 会被提交到 Brackets 主仓库。
5.4 代码评审
Brackets 团队成员会评审你的 Pull Request:通过则合并;如需修改,评审者会在 Pull Request 中留言,系统会通过邮件通知你。
5.5 更新已有分支与 Pull Request
如果评审后需要继续修改,务必在同一个分支(如patch-1)上更新,而不要为每次修改新建分支——否则核心团队难以一次性查看全部改动,甚至可能产生难以解决的冲突。流程示例:
- 查看 Pull Request 顶部的合并提示,形如
user1 wants to merge 1 commit into adobe:master from user1:patch-1,记住你的分支名。 - 进入你 fork 后的 Brackets 仓库页面。
- 点击Branches标签页。
- 点击进入你的分支(如
patch-1)。 - 在该分支上直接编辑提交。保存的编辑会作为新 commit 自动出现在原 Pull Request 中。
- 修改完成后,在 Pull Request 中追加评论(如 "Changes made -- ready for another review"),通知评审者可以再次评审。
六、当前无法本地化的部分(翻译限制)
以下是 README 明确指出的、暂时无法本地化的字符串与界面元素:
- 键盘快捷键:快捷键本身无法本地化(其显示标签与绑定规则硬编码)。
- Mac 上的部分原生菜单:仅硬编码支持英语、法语、日语三种语言。
- Windows 安装程序界面:仅硬编码支持英语、日语(且存在一定限制)。
- "Getting Started" 的本地化文件夹名:只能使用基本英文字符(见第三节末尾的硬性限制)。
为这些区域做翻译计划时,请以英文或上述硬编码语言为兜底,不要期待短期内在这些区域看到多语言效果。
七、字符串回退(fallback)机制
一个容易踩坑但很重要的机制是字符串回退:
某个 locale 中未定义的字符串,会先回退到不带连字符的通用语言(例如
en-ca回退到en),若仍不存在,再回退到 src/nls/root/strings.js 中的英文原串。
这意味着:
- 翻译一个带地区后缀的 locale(如
en-gb)时,不必翻译全部字符串,缺失条目会自动借用通用语言(en)的翻译。 - 任何语言都永远以英文为最终兜底,所以新翻译永远不会因为缺词而显示空白。
- 这一行为由 require.js i18n 插件的加载规则保证:插件按“精确 locale → 语言代码 → root”的顺序逐级解析模块。
理解了回退链,你就可以采用“先翻译语言级目录,再为特定地区补充少量差异条目”的分层策略,减少重复劳动。
八、实践建议与自检清单
结合 src/nls/README.md 的流程与仓库源码,给翻译贡献者几条可操作的建议:
- 先跑通流程再加量:先翻译一小批高频字符串(菜单、对话框标题),按第五节流程提交 PR,熟悉评审节奏后再批量翻译。
- 善用回退机制:地区级 locale 只翻译与通用语言不同的条目,能显著减少工作量。
- 占位符与 HTML 原样保留:
{0}、{1}、{APP_NAME}等占位符以及<span>、<a>等标签必须原样保留,只翻译文本内容(对照 src/nls/root/strings.js 可看到带占位符的典型条目)。 - SHA 注释是硬要求:无论新增还是修改,最后一行注释缺失或不正确都会给维护者带来对账困难,务必按第 6 步补齐。
- 示例项目目录名只用拉丁字符:即使你的语言是中文、阿拉伯语等,
samples下的文件夹名也要保持纯英文字符,否则欢迎页路径解析会失败。 - 自检清单:翻译完成后依次核对——
nls/strings.js已注册语言、strings-app.js有LOCALE_*条目、urls.js指向的 samples 目录真实存在、strings.js 末尾有 SHA 注释、能在 Debug > Switch Language 中看到并切换到你的语言。
按照以上流程,从新增语言到持续维护,再到通过 Pull Request 提交社区贡献,你就完整掌握了 Brackets 本地化工作的全貌。仓库内 src/nls 的 30 多个语言目录就是最好的活教材,直接对照某个已完成的语言(如 src/nls/zh-cn 或 src/nls/fr)进行比对翻译,是最快的学习路径。
【免费下载链接】bracketsAn open source code editor for the web, written in JavaScript, HTML and CSS.项目地址: https://gitcode.com/gh_mirrors/br/brackets
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考