l10n/i18n: 如何处理带有动态项目列表的短语?

l10n/i18n: how to handle phrases with dynamic list of items?

处理动态列表的翻译和本地化的最明智方法是什么?

假设我查询了数据库,得到了一个列表 ["Foos", "Bars", "Bazes"]。我们还假设该列表始终包含至少两项 - 我一定会为单项情况使用不同的翻译。

如果我需要像“我们的代码中有多种 Foos、Bars 和 Bazes 可供选择”这样的短语,我该怎么办? (假设列表项是动态的,所以我 不能 只是预翻译所有可能的排列,并且需要在 运行 时间做一些事情。)

我至少看到以下问题:

我的问题是,我什至不知道什么工具可以帮到我。我没有任何特定的编程语言要求,尽管 Python 或 JavaScript 是最好的。但我想我可以 运行 几乎任何事情,因为我可能可以构建一个 l10n 微服务并从我的项目中查询它。

我在遇到这个问题之前使用过 GNU gettext,但是我没有找到任何可以帮助我处理 API 和数据格式的东西。我能想象的最好的是 _("We have a wide choice of %s in our code", list_text) 并使用一些 DIY 技巧生成 list_text。我不确定 XLIFF 格式是否也有类似的内容。我在 npm 上找到 i18n-list-generator 但它是 way too simplicistic.

有没有人处理过这样的事情?你做了什么?是否有 任何 库可以处理这个问题 - 这样我就可以看看它的 API 并了解它是如何做的?

以下是我的处理方法:

  1. 没有串联。所有字符串连接都需要通过带占位符的格式字符串来完成。

  2. 仅使用支持 named/numbered 占位符的格式字符串。例如。 {FOO}</code> 而不是 <code>%s (这是为了允许参数重新排序)。命名占位符也更好,因为它们为翻译人员提供了更多上下文。假设我们正在使用 {FOO} 样式的占位符。

  3. 要呈现列表,我会使用几个格式字符串,例如:joinItem = "{LIST}, {ITEM}" 将项目附加到列表,joinLastItem = "{LIST} and {ITEM}" 附加最后一项。这将允许呈现 Foos, Bars and Bases 之类的字符串,更改标点符号,甚至在必要时反转列表的顺序。

  4. 最后,您可以使用最终格式字符串,例如weHaveTheseItems = "We have a wide choice of {ITEMS} in our code",假设 {ITEMS} 被替换为之前呈现的字符串。

无耻的自我推销:你可能想看看 Plurr 库,它支持这种 {FOO} 风格的占位符,以及复数形式(你可能需要这样的信息) ).它支持 JavaScript 以及其他语言。

这很痛苦,因为您指出并非所有语言环境都可以支持“、、、、和”形式。

受@GSerg 和@Igor Afanasyev 的启发,我想出了一个基于 GNU Gettext 的解决方案,如下所示(伪 gettext 调用):

GettextPlural(
    // TRANSLATORS: For multiple "choices", each will be prefixed with a new-line (\n)
    "We have a wide choice of {choices} in our code",
    "In our code we have a wide choice of{choices}", choices.Count)

应该像这样打印:

"We have a wide choice of FOOs in our code"

"In our code we have a wide choice of
FOOs
BARs
BAZs"

记得将 --add-comments=TRANSLATORS 粘贴到您的 xgettext 调用中。

出于 Web 目的,您可以使用 <ul><li>...</li>... </ul> 或其他代替 \n

好处是布局至少与 UI 布局 一样通用,但您仍然允许 non-English 左右的语言环境复数形式。

有些语言只有一种复数形式,因此它们的翻译必须同时适用于单选和多选,因此特别是,它们不能有条件 new-line。