应用的国际化和本地化,第2部分:Web工具

图片由费伦茨AlmasiUnsplash

在本教程的第二部分中,我们将学习如何选择合适的工具来支持带有传统HTML模板组件的现代React web应用。

查看本系列的第1部分在这里

遗留应用程序,遗留工具

在选择适合本地化产品的工具时,了解现有代码库的技术状态是一个重要的考虑因素。188bet金宝搏官网OkCupid是一个有17年历史的代码库,但令人耳目一新的是,我们的大多数应用程序都在一个单一的页面React应用程序中。尽管如此,我们仍然有一些顽固的遗留页面和我们支持的较老的REST端点。因此,我们确实需要能够满足应用程序需求的工具。

对于我们旧的代码库,包含了我们旧的基于模板的web文件,REST API,由移动应用加载的web视图,以及一些旧的香草javascript文件,我们最终使用了一个自定义实现gettext,一个成熟的GNU库,其中包括一套简单而健壮的本地化实用程序,例如搜索关键字文件,并将它们提取为以目录格式文件类型称为的消息可移植对象,或PO文件。实际上,我们将更新这些旧文件以使用gettext关键字,并提取他们的PO目录提交给译者。

为此PO文件是伟大的,因为他们不仅支持翻译所需的典型的键-值对,但也支持大量的可选的元数据字段,如评论可以填充帮助译者更高的保真度图片如何使用给定字符串或应该被解释。同样值得注意的是Mozilla已经发布了一个初始版本流利的这是一种非常灵活的本地化消息语法,我认为这是值得考虑的,因为它似乎立刻就能解决许多国际化问题。随着它的成熟,我们肯定会密切关注它。

React App, React Tools

对于大量面向用户的前端web代码,我们的单页React应用程序,我们最终决定使用一个名为麟贵JS,一个小型的香草JavaScript库,带有一些非常有趣的React和Babel绑定。它有一个国际化解决方案的通用工具包,如变量插值,复数规则,翻译与语法性别,日期/时间/数字格式,等等。很棒的是,Lingui既可以在React上下文中使用,也可以在普通的ole JavaScript上下文中使用,这意味着无论我们是否在严格的React上下文中,我们都可以灵活地利用Lingui。然而,我们决定选择这个工具的一个主要原因是,它的API和自动化能力非常接近于我们在当时的代码库状态下所获得的即时解决方案。它还允许各种配置,其中一个配置包括使用PO文件,其中的消息编码在ICU消息格式,为我们提供PO文件的简洁性和元数据,以及来自ICU消息格式的附加功能,如语法性别和类似jsx的标记化。

在本地化应用时,我们可以执行一些重构来使用Lingui,然后利用将所有面向用户的信息提取到我们的PO目录文件中这样就可以把它们发给翻译人员。让我们来看看一个简单的例子,看看我们原来的自定义代码是什么样子的,然后重构一下,分解一下Lingui是如何帮助我们实现我们的目标的:

需要好好重构的旧代码

国际化这个组件有几个主要问题。首先,h2它的内容使用了一个自定义格式组件,可以将复杂的值插入到字符串中,这很好,但它既不考虑复数规则,也不考虑语法性别规则。在第一个短语中,{username}喜欢你!,有一些语言,如意大利语,句子的其余部分的翻译取决于性别用户名.在第二个例子中,我们总是显示单词其他用户无论价值如何numberOfLikes.在英语中,这是不正确的,因为值可以是1,然后消息应该是其他用户.这很好,只要检查numberOfLikes = = = 1然后显示不同的消息,对吧?哦,不…许多其他语言有不同的复数规则,其中单词或短语的变化取决于主语的值是否等于1、2、5或21……你明白了吧,每种语言中都有特定的规则(以及关于ordinality,如第一个第二个第三等等)。

最重要的是var这里的定义有点笨拙,需要依赖于占位符格式,而占位符格式不是React原生的,这意味着想要使用它的开发人员需要了解它的具体工作原理。让我们看看如何处理Lingui:

麟贵的例子!

这看起来好多了,所以现在让我们看看当这些消息被拉出到我们的目录中时,它们将被提取到什么。在这里,是否是消息的ID(在我们的例子中是源英文字符串),以及msgstr是翻译后的版本(在本例中,是英文,但如果这是翻译的,它将是文本的翻译版本):

我们可以看到选择复数在ICU消息格式中被拉出到各自的语法中,允许我们将这些字符串发送给翻译人员,并允许他们适当地用不同的值填充它们,包括msgstr包括翻译的ICU复数年代和选择但是如果其他语言有不同的复数规则,那么msgstr这些规则会改变,不是吗?

这是正确的,为了演示的目的,想象一下有一个略微不同的组件来表示一个较短的复数。当我们把我们的信息翻译成波兰语时,就会发生这样的事情:

这就是临桂之美发挥作用的地方。我们可以只使用源语言所需的复数形式来定义组件,剩下的部分由Lingui的宏组件来处理。这些宏杠杆巴别塔的宏钩入Babel来运行代码的编译时转换。当我们提取消息时,将使用宏来告诉Lingui应该提取一条消息以及它应该包含哪些元数据。编译时,宏将替换from的引用@lingui /宏参考@lingui /反应包中存放了“真正的”React组件。这些都是上下文。消费者麟贵的年代I18nProvider并且可以从活动目录中读取特定于语言环境的复数数据,并准确地知道如何将翻译后的信息进行复数或性别化。

他们的文档中还列出了Lingui的许多其他伟大功能,但是有太多对我来说完全覆盖在这篇文章中,我将离开麟贵的讨论与评论,它已经相当人体工程学,容易适应本身在许多不同的情况下在我们的不断变化的反应的代码库,这是绝对值得考虑。

查看本系列的第3部分在这里

188bet金宝搏官网OkCupid科技博客

阅读OkCupid工程团队每天连接数百万人的188bet金宝搏官网故事