国际化和本土化应用(第3部分):技术挑战

尼克·布兰德
7月16日 · 11分钟阅读
拍摄者Michael Dziedzic.uns

在这四部分教程的第三部分,学习如何解决语言的各种注意事项和细微差别。这包括多元化,可访问性,格式化日期和数字,以及更多!

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

让Unicode引领方式

2003年,Unicode联盟发布了称为项目的第一个主要版本公共区域设置数据存储库,简称为CLDR,这是一个庞大的XML数据集,包含许多国际化、本地化和翻译特定的数据和规则。从那时起,这个存储库就不断发展,在撰写本文时已经达到了主要的39版。有些事情由CLDR编码包括:

  • 语言名称的翻译
  • 领土和国家名称的翻译
  • 货币名称的翻译,包括单数/复数修改
  • 的翻译工作日时代,一天中的一段时间,完整和简短的形式
  • 时区的翻译和示例城市(或类似)时区
  • 日历字段的翻译
  • 格式化/解析日期或一天中的时间的模式
  • 用于编写语言的示例套字符
  • 格式化/解析数字的模式
  • 语言适应奇异,复数和序数措辞规则
  • language-adapted规则排序
  • 在传统数字系统中格式化数字的规则(如罗马数字亚美尼亚数字, 等等。)
  • 将数字拼写为单词的规则
  • 规则音译脚本之间。它的大部分是基于BGN / PCGN皈依天主教

利用这些数据就像下载和解析XML一样简单,但是,依赖标准化的、cldr支持的库或api通常是有用的,例如INTL API在大多数现代浏览器和最近版本的节点中提供(或类似的特定于语言/平台的CLDR数据实现)。

Unicode联盟考虑的另一个问题是如何通过使用Grapheme集群,以便在保留有意义的文本块的同时,确定一组字符可以被分割的适当位置。仅这一点就可以构成一篇完整的文章,但可以这么说string.slice(...)如果您需要以任何原因手动操纵您的琴弦,就不够。

地区特定的格式

当然,每种语言环境都有处理特定数据格式化的独特方法。最常见的例子,也是你以前很可能遇到过的,是每种货币都使用一些特定的符号,这样一个.最重要的是,由于每个区域代表数字的方式,货币在区域中也可以在地区的不同方式进行不同。例如,让我们使用Intl.numberformat.API检查的几个数字:

货币格式的差异

当然,这适用于不仅仅是货币,还适用于类似的东西,它们全部用于OKCupid以表示两个用户之间的匹配188bet金宝搏官网百分比。以下是本地化百分比的示例:

百分比格式化的差异

这些API强大令人难以置信的强大,并且是最近浏览器的一部分(并且在最近的节点版本中本身)。他们还提供了用于使用不同数字集的物品为某些语言设置的方式格式化数字,本地化距离/速度/度量标准测量等等。

我们还应该确保在应用程序中正确地本地化其他内容,如日期、时间、相对时间,甚至列表:

利用Intl api的例子

还值得一提的是,在本地化值时经常被忽视的另一件事是,“按字母顺序排序”的概念会根据使用的语言而改变,正如给定语言中使用的符号会改变和简单。种类(...)默认情况下,肯定不会考虑区域设置。幸运的是,CLDR让我们再次覆盖提供整理规则排序也可以本地化。的Intlapi还公开排序器为这个目的。

当然,所有这些信息的最佳真理源始终是公共语言环境数据存储库的最新版本,并利用此数据源的任何API实现(例如Intlapi)是确保为给定语言环境提供正确数据的好方法。

可访问性

也许软件中更重要的主题之一,特别是在过去几年中,可访问性是大量应用程序的核心特征。Mozilla将可访问性定义为

可访问性是指让你的网站能够被尽可能多的人使用。我们传统上认为这是针对残疾人的,但使网站可访问的做法也有利于其他群体,如使用移动设备的人,或那些网络连接缓慢的人。

如果我们从表面上看这个定义,那么我认为这里有一个扩展.我们正致力于将我们的软件开拓整个人,以前有限或没有有意义的访问权限,并使其与这些人一起访问和相关。

对于开发人员来说,这意味着我们还应该确保我们为确保我们的应用程序的所有工作都可以直接与我们为国际化应用程序进行国际化的工作。如果我们提供意义可访问性标签altaria - *属性等,我们还应该确保它们的正确翻译,这很容易忽视。

此外,我们应该专注于,确保这些也是正确的本地化。确保我们的文档是正确标记的(例如,使用HTML是很重要的属性)因此,可以让其他软件等待辅助设备知道有问题的文档处于某种语言。至于手势,想象一下习惯于阿拉伯语或希伯来语等左右的语言:人们如何正确地本地化一个像“刷左”和“刷新的”这样的功能?当然,这些是从西方体验中诞生的,有趣的是考虑如何在最初设计的布局和剧本中抵押。

API设计,重新设计?

本地化应该在哪里发生?

在应用程序中完成可本地化内容时,对用户预期在您的Web服务器或服务提出请求时,将读取对本地用户的内容将是至关重要的。尽管这是HTTP内容协商的具体特征,但是具有在整个系统中可以在整个系统中传播用户的语言环境代码的均匀方式的概念可以被抽象地和跨各种协议应用。当然,当然有其他方式表示语言偏好,也许最常见的是,否则是URL查询参数的使用,例如www.somesite.com/home ? lang = en.当然,基于标头的方法和基于显式参数的方法之间存在权衡的权衡,并且应该在您的应用程序中提供其他因素,例如请求/响应缓存机制。

对于许多在设计时没有考虑到国际化的api来说,这可能是一个常见的陷阱,确保每个数据点(或至少它们的一些表示)都有一种方法来实现它是至关重要的.在国际化服务或API的国际化时,使用字符串直接合作,因为它允许客户端和服务器代码允许删除对变量数据的依赖性。例如,让我们向我们抽象地绘制一组关于我们想要获得一些可以在后续切线请求中使用的数据的关于的一组信息:

获取“API / MENU / PIZZA_TOPPPINGS” - > [奶酪“,”PEPPERNI“,”VEGGIE“]
POST "api/my_pizza/add_topping"——> ("Pepperoni")——> {success: true}

考虑一下,如果我们想要支持返回这些数据点的翻译/ pizza_toppings.因此,我们的用户可以看到文本的本地化版本,端点/ add_topping.可能无法解决以外的值["奶酪”、“意大利辣香肠”、“素食”)等等,因此如果我们将这些值转换为另一种语言的等同物,我们的客户将发送虚假请求。与以下内容相比:

获取“API / MENU / PIZZA_TOPPPINGS” - > [
{id:1220,名称:“奶酪”},
{id:1234,名称:“Pepperoni”},
{id: 1002, name: "Veggie"}

POST "api/my_pizza/add_topping"——>(1234)——> {success: true}

通过将api和服务的输入和输出结构成更规范化的格式,我们现在可以简单地转换名称的字段/ pizza_toppings.有效负载,不需要担心增加对其他语言的支持而破坏我们的软件。对于某些人来说,这似乎是显而易见的,但我要强调的是,在高速的情况下,很容易忽略一些你目前没有设计的内容(后见证是20:20)因此,对于最初预期的软件来说,它可以理解的是,对于支持本地化等特征,工程师可以很容易地选择了前一个例子,以便简单起见。

最后,值得花一点时间来分析当前应用程序的架构和问题,以及是否有必要(以及随后,可能)来支持各种语言和地区。如果您有服务需要适应给定区域环境的语言,文化或法律要求,则这种可变性如何适合API和服务的当前架构。可以有可能需要提供服务专用于确定给定区域设置或区域的特征映射的任务。

样式,主题,资产

就像我之前提到过的那样,是某些语言的一个非常重要的句法特征。出于这个原因,我认为最好避免使用像CSS这样的代码文本变换或Javascript的String.toUpperCase对将显示给用户显示的消息的情况进行显式更改。您几乎可以保证这将无意中损坏某些时候留言的翻译。让我们来看看这里的一个例子,例如,我们希望利用用户的名称及其位置:

天真案例转型导致错误

嗯,现在我们实际上只是在土耳其语中误解了两条消息,因为我的名字不是缺口这个城市的名字不是Cİ数控İ奈特İ,无论字形的事实如何一世应该是一世在土耳其语中大写。

在谈到我们软件的造型时要记住的另一个重要件是确保我们的组件可以.如果一个短语在英语中只有几个单词或字母,那么在翻译成其他语言时,它的长度很容易翻倍或三倍(反之亦然)。这当然是设计问题的一部分,但我们也有责任确保在我们的设计中考虑到可变长度的字符串,这样翻译不会导致我们的组件以任何方式剪辑或损坏。

除了为内容设计不同的预期长度外,我们还应该记住,我们的组件应该以一种能够在各种语言的脚本中使用的方式构建,而不管具体情况如何所选脚本。拿到这一目标CSS作为一个例子:

使您的样式适用于多个文档方向类型

仔细使用开始结尾价值反对值将允许我们的样式表跨越语言轻松扩展脚本和脚本!整洁!

也许另一个区域真正让你的本地化工作脱颖而出.就像我之前提到的,颜色和象征都受文化和语言的影响,所以使用像ThemeProvider从风格的组件要根据应用程序的主动区域设置管理主题可能是一种非常有趣的方式,使您的产品在不同地区和语言中会更加自然地脱颖而出。例如,我们的错误消息的颜色可以为Western Ligales为红色,其中颜色通常与错误相关,但不是某些东亚语言环境,其中该颜色通常不与错误相关联。这是一个小小的例子,但语言环境特定主题的可能性实际上是无穷无尽的。

一个有趣的讨论点是Okcupid目前对本地化资产的态度。188bet金宝搏官网也许您的应用程序使用大量的静态图像。.但是,它现在意味着这些资产太需要本地化,如果您计划扩展到甚至是几(更不用说数十),基于特定地区创建/导出/导入这些资产的单调乏味将会线性增加设计师和开发人员。正因为如此,我们决定尝试在我们的资产中删除嵌入式语言,并使用更多可以在各种语言和文化中工作的中立资产。这里有一个非常简单的例子来说明这一点:

基于文本的资产与插图的资产和本机文本

左边用红色标出的元素实际上是从CDN加载的图像资源、文本和所有内容。右边的绿色部分,图像已经从文本中分离出来,这样文本内容和图像资源就可以在React / CSS中独立渲染,而不需要为每种语言部署大量的图像到CDN。

我们还创建了一些很酷的自定义文本呈现类,以本地化的方式处理样式。看看这个帖子在这里

它真的是一个常数吗?

我想通过为我遇到的问题提供一个小小的轶事来包装更具体的技术因素,以及它在我的代码中思考的哲学/建筑点。在某些时候,我有一条准备翻译的消息,无法弄清楚为什么这条消息没有被正确翻译。

它最后变成了翻译应用文件导入时,因为它被定义为一个常数,所以它从来没有重新评估后的最初评估(在这种情况下,它还没有最新的数据进行正确的评价)。

我们是常见的地方,让我们嘲笑我们的代码库,通常涉及采用基本数据类型,如字符串,并将它们作为常量声明一次,并在码库中的文件和模块中重新使用它们。但是,当您使用类似React提供商和上下文时应用跨组件或应用程序的语言环境时,您的“常量”现在可以根据应用程序的状态进行更改。这当然是一个很小的差异,但突出了这样一个事实,即像声明常量这样微不足道的事情需要根据国际化重新考虑。

写作软件也是一个很好的练习!解构您的工作并询问自己在做什么,无论您做什么都是有道理的,掌握掌握的艰难技能,但避免了这样的情况(以及仅限于一般的建筑物软件)的有价值。

请参阅本系列的第4部分在这里

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

从每天连接数百万人的工程团队阅读故事