Mozilla VPN客户端成功推出:德国与法国的本地化之旅

更新时间

引言

2023年4月28日,Mozilla成功在德国和法国推出其VPN客户端。自2020年以来,这款VPN客户端已在多个国家(如美国、英国、加拿大、新西兰、新加坡和马来西亚)上线,但用户界面之前仅支持英语。本文将详细介绍Mozilla生态系统内该产品本地化的过程和步骤。

项目开始

在2020年10月,参与该项目的小团队向我提出请求:我们计划使用Qt对现有的VPN客户端进行全面重写,使用一个代码库支持所有平台,并希望实现本地化。我们该如何进行?

首先,我要强调团队尽早沟通的重要性。这使我们能够了解现有的局限性,解释我们可以现实支持的内容,并设定明确的期望。在流程后期面临紧迫的截止日期时,被逼入困境绝对不是件愉快的事情。

初步本地化设置

这个项目无疑是一个有趣的挑战,因为我们之前没有Qt的经验,并且需要确保项目能够在我们的内部翻译管理系统(TMS)Pontoon中得到支持。

初步研究显示,Qt本地使用XML格式(TS文件),但这需要编写解析器和序列化器来支持Pontoon。幸运的是,Qt也支持从更常见的标准XLIFF导入和导出。

接下来的步骤通常是决定内容结构:我们想要TMS直接在主代码库中写入,还是希望使用一个专门的外部库进行本地化?在这种情况下,我们选择了后者,考虑到当时主代码库仍然是私有的。

一旦确定了格式和库结构,下一步是对现有内容进行全面审查: - 检查每个字符串的本地化问题。 - 在内容模糊或有变量在运行时替换的地方添加注释。 - 检查en-US内容的一致性,以防内容没有经过我们非常能干的内容团队的审查或创建。

值得注意的是,这一过程在很大程度上依赖于指定给项目的本地化项目经理,因为团队中有不同的技能组合。例如,我采取了非常实用的方法,通常直接写补丁来修复小问题,如缺少注释(这通常有助于减少修复所需的时间)。

在我的情况下,这是一种理想的方法: - 审查后,在Pontoon中将项目设置为私有项目(仅限管理员访问)。 - 实际将项目翻译成意大利语。这使我能够验证Pontoon中的所有设置是否正确,更重要的是,它使我能够识别我在初步审查中可能遗漏的问题。当你只是查看内容时,你的大脑运作方式与实际尝试翻译时是截然不同的,真是令人惊讶。 - 测试产品的本地化构建。通过这种方式,我可以验证我们是否能够使用TMS的输出,构建系统是否按预期工作,并且没有错误(如硬编码内容、在不同上下文中重复使用的字符串等)。

整个过程通常需要至少几周的时间,具体取决于同时进行的其他项目数量。

扩展与自动化

我非常喜欢在处理重复任务时进行自动化,并且在这个项目中我学到了很多关于GitHub Actions的知识。幸运的是,这些知识在后来的多个项目中也得到了帮助。

我注意到的第一件事是,我经常对源(en-US)字符串的两个问题进行评论:排版问题(直引号、三个点而不是省略号)、缺少字符串变量的注释。因此,我编写了一个非常基础的linter,在开发人员在拉取请求中添加新字符串时自动运行。

自动化的主要内容位于l10n库中: - 每天运行的自动化提取代码库中的字符串,并创建一个PR将其暴露给所有语言。 - 一个基本的linter检查本地化内容中的问题,尤其是缺少变量。这种情况比应有的更常见,主要是因为占位符格式与本地化者习惯的格式不同,并且可能会出现翻译记忆匹配——来自不同文件格式的已翻译字符串。

更新自动化尤为有趣。提取新的en-US字符串相对容易,得益于Qt命令行工具,尽管需要一些工作来清理生成的XLIFF(例如,将本地化注释从extracomment移动到note)。

在添加新语言环境的过程中,我们迅速意识到,仅更新参考文件(en-US)是不够的,因为Pontoon期望每个本地化的XLIFF都包含所有源消息,即使未翻译。

历史上,其他双语文件格式(如.po(GetText)和.lang文件)也是如此,但这并不一定适用于XLIFF文件。特别是,这两种格式都有自己的工具来将新字符串从模板合并到其他语言环境中,但XLIFF并没有这样的工具,它是一个在完全不同工具间使用的交换格式。

此时,我需要自动化来解决两个独立的问题: - 在更新en-US时,将新字符串添加到所有本地化文件中。 - 捕捉意外的字符串更改。如果一个字符串在没有新ID的情况下更改,Pontoon不会触发任何操作(现有翻译将保留,本地化者不会意识到更改)。因此,我们需要确保这些更改得到妥善管理。

以下是源XLIFF文件中字符串的样子: ```xml
服务条款

```

更新脚本的主要步骤如下: - 它以en-US XLIFF文件为模板。 - 它读取每个本地化文件,保存现有翻译。这些翻译存储在字典中,键是通过文件元素的original属性、trans-unit中的字符串ID和实际源字符串的哈希生成的。 - 然后,将翻译注入en-US模板并保存,覆盖现有的本地化文件。 使用en-US文件作为模板确保文件包含所有字符串。使用源文本的哈希作为ID的一部分将移除翻译,如果源字符串发生变化(在遍历en-US文件时生成的ID将没有匹配的翻译)。

测试

如何测试一个不公开可用、且需要付费订阅的项目?幸运的是,团队想出了一个聪明的主意,创建一个WASM在线应用程序,允许我们的志愿者测试他们的工作,包括通常不会在主用户界面中暴露的UI或对话框部分。

本地化字符串在构建过程中自动导入(l10n库作为子模块配置在代码库中),应用程序的截图也作为自动化的一部分生成。

结论

这个项目非常有趣,我认为它是一个成功案例,尤其是在不同团队之间的合作方面。非常感谢Andrea、Lesley、Sebastian在这个漫长的过程中始终给予支持和帮助,并不断关心本地化。

感谢我们本地化社区的出色工作,我们能够超越最低要求(支持法语和德语):在发布日,Mozilla VPN客户端已支持25种语言。

保持关注,期待更多精彩内容!

更新时间