YAOTU INSIGHTS

Brackets 国际化(i18n)实战指南:核心代码与插件本地化完整解析

Brackets 国际化(i18n)实战指南:核心代码与插件本地化完整解析
Brackets 国际化i18n实战指南核心代码与插件本地化完整解析【免费下载链接】bracketsAn open source code editor for the web, written in JavaScript, HTML and CSS.项目地址: https://gitcode.com/gh_mirrors/br/bracketsBrackets 是一款用 JavaScript、HTML 与 CSS 编写的开源 Web 代码编辑器其对用户可见文本的多语言支持Localization / i18n以nls目录 RequireJSi18n插件为核心。本文基于 LocalizationExample 示例插件文档 展开结合 src/strings.js、src/nls/strings.js 等核心实现系统讲解如何在 Brackets 核心代码与第三方插件中正确添加、加载和渲染本地化字符串。读完本文你将掌握如何为 Brackets 核心新增语言翻译、如何在 JS 与 HTML 中消费本地化字符串、如何编写一个完整支持多语言的插件以及插件字符串与核心字符串加载方式的区别。一、Brackets 本地化机制总览Brackets 为用户可见文本提供了基础的多语言支持详见 LocalizationExample/README.md。其设计核心约束是任何向用户显示文本的 JavaScript 和 HTML 代码都不应把英文静态字符串直接写在代码里而应把字符串集中存放在nls目录下的strings.js文件中再按需动态加载。整个机制由三个环节组成字符串仓库nls 目录所有语言的字符串以define({...})形式存放在 src/nls 下root目录存放英文基准串其余每个语言目录如fr、de、zh-cn存放对应翻译。字符串入口模块src/strings.js代码通过require(strings)加载 src/strings.js该模块内部借助i18n!nls/strings加载当前 locale 对应的strings.js。i18n 加载插件Brackets 使用 RequireJS 的 i18n 插件i18n!前缀按用户 locale 动态加载字符串文件并在缺失翻译时自动回退到英文保证任何语言环境下界面都不会出现空串。核心模块 src/strings.js 的实现清晰地体现了这一点var strings require(i18n!nls/strings), urls require(i18n!nls/urls), stringsApp require(i18n!nls/strings-app), ... module.exports strings;该模块还做了两件额外的事把APP_NAME、APP_TITLE、VERSION、BUILD_TYPE等应用级元数据作为额外全局值用正则{名称}替换的方式注入到所有字符串模板中并通过stringsApp叠加产品特定字符串最终将合并结果导出为Strings模块。这意味着strings.js中的字符串还支持占位符替换如{APP_NAME}为模板化文案提供了底层能力。二、locale 的注册与解析nls/strings.js 配置无论是核心还是插件都通过nls目录下的strings.js来声明支持的 locale 列表。以核心为例src/nls/strings.js 内容如下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 };几点关键说明root: true是必填项表示以root目录为英文基准root目录中缺少的翻译会自动回退到英文。每个键即一个 locale 标识命名遵循「语言-国家/地区」惯例如zh-cn、zh-tw、pt-br。locale 目录结构形如nls/locale/strings.js。新增一种语言时需要同时做三件事在nls/strings.js中登记 locale 键、新建nls/locale/strings.js翻译文件、在root/strings.js中补充英文基准串。目前核心支持 30 种语言/区域变体完整的翻译文件位于 src/nls 各语言目录中实际存在的内容可对照 src/nls 目录逐一查看。三、为 Brackets 核心新增本地化字符串3.1 英文基准串写入 root/strings.js新增英文字符串时把键值对添加到 src/nls/root/strings.js。该文件是 Brackets 全部用户可见文本的英文主档例如其中定义NOT_FOUND_ERR : The file/directory could not be found.,3.2 其他语言翻译写入对应 locale 目录其他语言的翻译应添加到nls目录下各 locale 文件夹内的strings.js。例如法语翻译应修改 src/nls/fr/strings.js。翻译文件与 root 文件采用相同的键名结构仅替换值为对应语言的文本。建议为某个语言补充翻译时与 src/nls/root/strings.js 保持键名一一对应未翻译的键会由 i18n 插件自动回退到英文因此部分翻译不会导致崩溃但完整的键覆盖才能提供最佳体验。四、在 Brackets 模块中使用本地化字符串4.1 JavaScript 中使用字符串在需要显示字符串的文件中加载Strings模块然后通过属性访问Strings require(strings);随后即可按属性名引用字符串例如Strings.NOT_FOUND_ERR在英文 locale 下返回 “The file/directory could not be found.”该键定义于 src/nls/root/strings.js。Strings模块会根据当前 locale 自动返回对应翻译无需在业务代码中做任何语言判断。4.2 HTML 中使用字符串Mustache 模板HTML 无法直接引用strings.js中的属性因此 Brackets 引入 Mustache.js 模板引擎来完成替换。JS 与 HTML 共用的字符串都存放在src/nls/root/strings.js但 HTML 中通过模板语法{{stringKeyName}}引用。例如h1 classdialog-title{{SAVE_CHANGES}}/h1渲染后得到h1 classdialog-titleSave Changes/h1其底层流程是Mustache 在 Brackets 启动、模块加载时运行——src/brackets.js 中的代码使用 i18n 加载对应的strings.js以 text 方式加载 HTML 文件内容以strings.js为数据源对文本执行Mustache.render最后将结果插入 DOM。实际证据可见 src/brackets.js$(body).html(Mustache.render(MainViewHTML, { shouldAddAA: (brackets.platform mac), Strings: Strings }));此外src/brackets.js 还通过Object.defineProperty(window, Mustache, ...)把 Mustache 暴露为全局对象并附带弃用警告建议插件改用brackets.getModule(thirdparty/mustache/mustache)获取。依赖 DOM 的核心代码在检查或操作 DOM 之前应监听htmlContentLoadComplete事件确保 Mustache 渲染完成。五、本地化准则与已知限制禁止拼接多个字符串键strings.js中的多个字符串键不应被拼接组合使用因为不同语言的词序差异很大例如形容词与名词的位置、主谓宾顺序硬拼接会导致翻译错乱。应尽量让每个键承载完整、自洽的句子。键盘快捷键暂不支持本地化目前 Brackets 尚未支持针对键盘快捷键keyboard shortcuts的本地化快捷键相关显示不在 i18n 覆盖范围内。六、插件本地化实战LocalizationExample 全解析插件本地化的机制与核心模块几乎一致同样使用 RequireJS 的 i18n 插件按 locale 动态加载strings.jsJavaScript 通过属性名引用字符串HTML 片段则借助 Mustache 插入本地化文本。完整示例见 src/extensions/samples/LocalizationExample。6.1 运行示例插件示例插件默认位于samples目录不会被自动加载将其移动到用户插件目录extensions/user/即可运行。加载后它会在Edit 菜单末尾新增一个 “My New Command” 菜单项点击该命令会先弹出一个包含本地化文本的 alert随后展示一个包含本地化 HTML 内容的模态对话框。6.2 目录结构与各文件职责示例插件的目录结构如下与 README 描述一致LocalizationExample/ ├── main.js # 加载插件 Strings 模块并用 Mustache 本地化 HTML ├── package.json # 声明支持的语言与本地化元数据 ├── strings.js # 用 i18n 加载 nls 目录中的 strings.js ├── htmlContent/ │ └── sampleHTMLFragment.html # 待 Mustache 本地化的 HTML 模板 └── nls/ ├── strings.js # 配置 i18n指定 root 目录并列出插件支持的 locale ├── root/ │ └── strings.js # 英文root字符串 └── fr/ └── strings.js # 法语字符串各文件具体职责如下main.js—— main.js 是插件的核心逻辑var CommandManager brackets.getModule(command/CommandManager), Menus brackets.getModule(command/Menus), Dialogs brackets.getModule(widgets/Dialogs), Mustache brackets.getModule(thirdparty/mustache/mustache); var browserWrapperHtml require(text!htmlContent/sampleHTMLFragment.html); var Strings require(strings); function testCommand() { window.alert(Strings.ALERT_MESSAGE); var localizedTemplate Mustache.render(browserWrapperHtml, Strings); Dialogs.showModalDialogUsingTemplate(localizedTemplate); } var myCommandID localizationExample.command; CommandManager.register(Strings.COMMAND_NAME, myCommandID, testCommand); var menu Menus.getMenu(Menus.AppMenuBar.EDIT_MENU); menu.addMenuItem(myCommandID, null, Menus.AFTER, myCommandID);要点require(strings)加载本插件的字符串模块指向插件目录下的 strings.js核心字符串则用brackets.getModule(strings)。命令名通过Strings.COMMAND_NAME本地化因此菜单项文本随 locale 变化。Mustache.render(html, Strings)以字符串模块为数据源渲染模板再交给Dialogs.showModalDialogUsingTemplate展示。package.json—— package.json 声明语言支持与本地化元数据{ name: localization-example, title: Localization Example, description: A guide on how to localize your extension., version: 1.0.0, author: The Brackets team, license: MIT, engines: { brackets: 0.42.0 }, i18n: [en, fr], package-i18n: { fr: { title: Localisation Exemple, description: Un guide sur la façon de localiser votre poste. } } }i18n: [en, fr]声明插件支持的语言列表。package-i18n提供各语言下的本地化元数据如 Extension Manager 中显示的标题与描述键为 locale值为覆盖字段。strings.js—— strings.js 是插件字符串入口一行即完成动态加载module.exports require(i18n!nls/strings);nls/strings.js—— nls/strings.js 配置 i18n指定 root 目录并列出插件支持的 localemodule.exports { root: true, fr: true };nls/root/strings.js—— 英文基准串查看完整文件define({ COMMAND_NAME : My New Command, ALERT_MESSAGE : This is a sample alert message, DIALOG_TITLE : Localized Dialog Example, DIALOG_TEXT : This is an example of localized text in Brackets, DIALOG_OK : OK });nls/fr/strings.js—— 法语翻译查看完整文件键名与 root 一致仅值不同如COMMAND_NAME: Ma nouvelle commande。htmlContent/sampleHTMLFragment.html—— Mustache 模板查看完整文件div classsample-localized-dialog modal div classmodal-header h1 classdialog-title{{DIALOG_TITLE}}/h1 /div div classmodal-body {{DIALOG_TEXT}} /div div classmodal-footer a href# classdialog-button btn primary contenteditable="false">【免费下载链接】bracketsAn open source code editor for the web, written in JavaScript, HTML and CSS.项目地址: https://gitcode.com/gh_mirrors/br/brackets创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考