本地化¶
Mozilla 的本地化¶
在 Mozilla,本地化由全球各地的语言社区管理,他们负责将 Mozilla 软件高质量地语言和文化适应到 100 多个语言环境中。
本地化管理的具体流程因项目而异,但在 Gecko 应用程序的情况下,本地化主要通过名为 Pontoon 的 Web 本地化系统完成,并存储在 firefox-l10n GitHub 存储库中。
开发人员应使用本地化和国际化系统保持其代码的可本地化性,并充当 en-US 语言环境的本地化人员,该语言环境用作 源 语言环境。
在开发人员和本地化人员之间,存在一个复杂的工具、测试、自动化、验证器和其他检查的生态系统,另一方面,还有 本地化团队 推进的管理、发布、社区和质量流程。
内容与 UI¶
本地化的两个主要类别是内容本地化与 UI 本地化。
前者通常涉及处理大块文本,例如文档、帮助文章、营销材料和法律文件。
后者是在处理 Firefox 等应用程序的用户界面时最主要的类型。
本文将重点介绍 UI 本地化。
生命周期 & 工作流程¶
1) 新功能¶
可本地化 UI 的典型生命周期始于 UX/UI 或新功能需求,该需求应附带 UX 模型,其中涉及所谓的 复制 - 新 UI 部分中使用的原始内容。
2) UX 模型 + 复制审查¶
带有复制的 UX 模型是第一步,本地化团队应对此进行审查。他们的目标是识别以后可能出现的潜在文化和本地化挑战,并确保 UI 在语言、文化和技术层面都已准备好进行本地化。
3) 修补程序 l10n 审查¶
完成后,下一阶段是前端工程师创建实现新 UI 的修补程序。这些修补程序应已包含 复制 并将字符串放置在源语言环境 (en-US) 的本地化资源中。
开发人员通过选择我们称为 L10n ID 的特殊标识符以及可选地传递给翻译的变量列表来使用本地化 API。
我们称之为“社会契约”,它将 l10n-id/args 组合绑定到 UI 中使用的特定源翻译。
本地化人员期望开发人员通过确保翻译将在指定位置使用,并且将与源翻译相对应来维护该契约。如果要更改该契约,开发人员将需要对其进行更新。更多信息请参见部分 6) 字符串更新。
接下来的审查来自本地化团队或熟悉国际化和本地化系统的经验丰富的前端工程师,确保修补程序正确使用正确的 API 并且代码已准备好合并到 mozilla-central 中。
4) 在 firefox-l10n-source 和 gecko-strings 中公开¶
修补程序合并到 mozilla-central 后,字符串在合并到 firefox-l10n-source(一个包含 Firefox 所有发布版本(Nightly、Beta、Release、ESR 等)的字符串的统一存储库)之前不会公开给本地化。
此存储库中的自动化每天两次从 gecko-dev 将新字符串提取到一个单独的 更新 分支中。此分支充当缓冲区,以避免将潜在问题暴露给 100 多个语言环境。本地化团队将对引入的字符串的可本地化性进行最终检查。如果出现问题,可能会要求开发人员合并后续操作,或者可以在 Sheriff 的帮助下撤消修补程序。
作为最后一步,字符串将合并到 主 分支中,该分支将公开到我们的 Web 本地化工具 Pontoon。
在当前从 Mercurial 迁移到 GitHub 的过程中,两个统一的 Mercurial 存储库中的源字符串会发生并行的旧版流程(称为 跨通道):gecko-strings-quarantine(预审)和 gecko-strings(后审)。这些字符串镜像 firefox-l10n-source 中的字符串,目前用于比较 GitHub 工作流的输出以确保一致性。跨通道 将在未来逐步淘汰。
5) 本地化¶
字符串公开到 Pontoon 后,本地化人员将开始为新功能提供翻译,无论新字符串仅在 Nightly 中还是合并到 Beta 后。目标是在尽可能多的语言环境中尽早准备好尽可能多的 UI,但该过程是持续的,并且我们能够在翻译不完整的情况下发布 Firefox,如果缺少字符串,则回退到备份语言环境。
翻译在 Pontoon 中完成后,最终的本地化字符串将存储在 firefox-l10n 中。
6) 字符串更新¶
在软件生命周期的后期,某些字符串可能需要更改或删除。作为一般规则,一旦字符串合并到 mozilla-central 中,对现有字符串的任何进一步更新都将需要遵循这些指南,而不管自上次更改以来经过了多长时间。
如果只是删除字符串,则工程师需要做的就是将其从 UI 和 mozilla-central 中的本地化资源文件中删除。
如果是更新,我们目前有两个“级别”的更改严重性
1) 如果更改很小,例如更正拼写错误或大小写,则开发人员应更新 en-US 翻译,而不更改 l10n-id。
2) 如果更改以任何方式影响消息的含义或语气,则请求开发人员更新 l10n 字符串 ID。
后者被视为开发人员和本地化人员之间社会契约的更改,并且需要更新 ID。
在 Fluent 的情况下,对消息结构的任何更改(例如添加/删除属性)也需要更新 ID。
l10n 工具将识别新的 ID 为未翻译,并将旧的 ID 识别为已弃用。这将使本地化人员有机会查找和更新翻译,同时旧字符串将从构建过程中移除。
这两个严重级别之间存在灰色区域。如有疑问,请随时请求本地化团队的反馈或审查,以避免字符串合并后出现问题。
选择 L10n 标识符¶
为本地化消息选择标识符很棘手。它可能看起来类似于选择变量名,但实际上,它更接近于设计公共 API。
一旦定义,l10n 标识符就会与 100 多个语言环境中的每个语言环境中的翻译消息相关联,并且尝试将该字符串在所有语言环境中迁移到不同的标识符将变得非常昂贵。
此外,在 Fluent 中,标识符用作在格式化消息失败时错误情况下显示的最后手段字符串,这使得选择有意义的标识符变得特别有价值。
最后,l10n 资源会混合并匹配到本地化上下文中,在这些上下文中避免来自两个不同文件的两个字符串的标识符冲突变得很重要。
出于所有这些原因,与 ok
或 ok-button
等短标识符相比,更长的标识符(例如 privacy-exceptions-button-ok
)更可取。
本地化系统¶
Gecko 有两个主要的本地化系统:Fluent 和 StringBundle(一个旧版系统)。
Fluent¶
Fluent 是 Mozilla 设计的一种现代本地化系统,旨在解决旧版系统的挑战和限制。
它非常适合现代 Web 开发周期,提供许多本地化功能,包括良好的国际化模型和强大的双向支持。
要了解有关 Fluent 的更多信息,请遵循 Firefox 开发人员的 Fluent 指南。
StringBundle¶
StringBundle 是主要用于 C++ 代码本地化的运行时 API。消息存储在 .properties 文件中,并使用 StringBundle API 加载,然后通过命令式调用从那里检索。
该系统提供外部位置参数,可以将其放置到字符串中。仅在认真考虑后才能添加新的 StringBundle 消息。