第一:
正如 svenfuchs 所写,I18n 是一个为许多翻译和国际化方法提供模块的框架。
'gettext' 只是众多模块之一。
所以使用I18n确实没有问题。
Rails 应用程序的默认设置是将 I18n 与 YAML 后端一起使用,我理解您的部分问题是将该后端与其他后端进行比较。
恕我直言,基于 gettext 和 YAML 的方法有两个主要区别:
获取文本
gettext 的一个想法是,翻译应用程序不是一个单一的事件,而是一个生命周期过程。
它是为支持这个生命周期而构建的。
gettext 旨在使用简单的英语作为翻译的键。所以想法是用英语编写应用程序并标记所有要翻译的文本,通常用_()包装。
因此,应用程序源代码很容易用英文阅读。
然后一个程序扫描所有源代码并提取要翻译的文本并构建这些文本的存储库(.pot 文件)。
在下一步中,生命周期来了,存储库与现有翻译(.po 文件,一个用于每个目标语言)和新的或更改的项目都被标记。
成熟的编辑通过关注新的和更改的项目来支持翻译。此外,项目特定的词典可以支持部分自动翻译。
gettext 是flat,这意味着每个关键短语在翻译文件中只翻译一次。没有等级制度。但有上下文。在翻译文件中,列出了一个关键短语的所有源代码位置。有权访问源代码的编辑器可以显示源代码以及翻译(有些人会这样做)。
最后,.po 文件被翻译成机器可读的快速访问形式(可以是 .mo,经典标准,或数据库或 json 或……)
YAML
另一方面,YAML 是分层的,因此很容易在不同的上下文中产生不同的翻译。
I18n 使用此结构来支持scopes,并在使用以点开头的键时使用当前文件路径作为作用域。
没有关于项目中使用密钥的信息(除非是自动范围,但密钥可能会在其他地方明确使用)。
没有信息,有没有变化。
除非您的 IDE 支持您,否则开发人员必须找到在 YAML 中放置密钥的正确位置,并且搜索用法可能很麻烦。
其他答案中说了很多。
I18n
我故意说YAML而不是I18n,因为I18n是一个国际化的框架(不仅仅是翻译),而YAML 只是一种可能的后端。
I18n 中的复数支持不同于普通 gettext 的复数支持。我没有他们如何合作的经验。
示例
gettext 带位置参数:
sprintf(
_('Do you really want to delete tour %1$s_%2$s? Only empty tours can be deleted!'),
tag, idx)
翻译是文本文件,但 PO 编辑器提供 GUI:
#: js/addDelRow.js:15
msgid "" "Do you really want to delete tour %1$s_%2$s? Only empty tours can be deleted!"
msgstr "" "Wollen sie die Spalte %1$s_%2$s wirklich löschen? Nur leere Spalten können "
"gelöscht werden."
YAML 带参数:
来源
<%= t('.checked_at', ts: l(checked_at), user: full_name) %>
翻译
来自
en:
hotels:
form:
checked_at: „set to checked by %{user} on %{ts}“
到
de:
hotels:
form:
checked_at: "geprüft gesetzt am %{ts} von %{user}“
结论
YAML 更容易上手,尤其是在您有 IDE 支持的情况下。
Vanilla RAILS 内置了它。
不是本地语言。第一个翻译可以是任何语言。
随着项目的增长和多种语言,我的 YAML 文件倾向于重复(相同的翻译分散在层次结构中)和跟踪更改,因此新的翻译很麻烦。
gettext 需要一个额外的工具链,因此设置起来更加困难。
支持开发应用程序持续翻译的全生命周期。
它基于英文源代码。
我通常使用两者中最好的部分,使用 YAML 进行国际化(数字和日期格式,也许是模型名称?)和 gettext 进行翻译。