对Ruby有些新意我正在探索现有的库来执行我在其他脚本语言中通常所做的事情,而且我对可能在Sinatra / / s之上构建的东西可用的本地化库感到有点困惑续集(Rails / AR根据我的口味有点过于自以为是)。
现在,虽然this wiki page遇到了一对(i18n,r18n,GetText),但显然在Padrino中使用了一个额外的库(基于来自Rails的i18n的东西?);而且显然还有更多。
除了明显的(即GetText mo / po样式与yml文件)之外,我对这些选项可能有何不同感到困惑。除了说它们存在之外,维基在这方面并没有太多指出;不是他们如何不同。
除此之外,实际上每个文档似乎都涵盖了其中的一个(通常在RoR上下文中)。此外,这些选项在仔细检查时看起来并不完全不相容 - 在某种意义上说,如果我理解这一点,他们可以在很大程度上理解彼此的文件。
这里的任何人都可以快速提供这些库的简要解释/概述,并概述它们之间的区别吗?关于性能的一些指示也是受欢迎的,如果你知道任何(除了fast_gettext文档中的那些,考虑到我对这些选项之间的差异缺乏理解,这没什么意义)。
答案 0 :(得分:30)
如果不了解Ruby中i18n / l10n库的一些历史,我可以看到这种情况如何令人困惑。我应该就此写几句话,但是现在我会尝试从我的角度给出一个概述:
Gettext显然是这场比赛中最年长的球员,它继承了其为C主导世界发明的祖先的优点和缺点。它具有一个需要的大多数功能,附带一些其他人缺乏的工具支持(如桌面po文件编辑器),并在所谓的企业界广泛接受。
Gettext这样定义了一个API,基本上有两个库在Ruby世界中实现它,传统的Ruby Gettext包由Masao Mutoh和fast_gettext gem由Michael Grosser
Ruby Gettext非常强大,并且提供了许多您可能需要或不需要的功能。另一方面,fast_gettext gem专注于原始速度,并作为一个闪亮的,现代的代码风格的Ruby库实现,很容易被破解,作者是一个非常聪明和支持的人。在这两个中,我个人强烈推荐fast_gettext。
I18n gem是几年前存在的各种Ruby i18n / l10n解决方案共同努力的结果,并且所有人都在这个时间点出于各种原因努力取代Gettext。由此产生的I18n API基本上涵盖了当时所涉及的所有i18n / l10n解决方案的要求和用例,包括Gettext的API。因此,今天的Ruby I18n API是90年代初期Gettext API的超集。
今天I18n gem是shipped with Ruby on Rails的官方解决方案,但它通常也是Ruby世界中可能的most popular。
I18n gem也使它成为very easy to extend功能集,并添加缓存,其他存储机制(如Gettext po文件,数据库表,键值存储;存储默认为纯Ruby文件和YAML)等内容。它附带number of modules(但外部或自定义模块可以轻松制作,测试和集成)。
对于由社区维护的Ruby on Rails(在其他项目中也很有用)使用的字符串,70+ languages(语言环境)有翻译文件。
我不能说R18n,除非它是在I18n首次发布之后发明的,据我记得它来自Merb社区。它似乎在俄罗斯的Ruby世界中相当强大,但我对所有这些断言可能都错了。
所以,除非你有充分的理由选择任何其他解决方案,否则我强烈建议使用I18n。
然而另一方面,这意味着什么,因为I've been leading this project或多或少都是因为它被发明了。
我希望这会有所帮助。
[EDIT]添加了各种参考文献的链接
答案 1 :(得分:5)
I18n是主流。
R18n是一种替代方案,具有一些额外的功能(模型翻译,语法糖)以及意识形态和架构的一些差异(通过强大的过滤器实现灵活的可扩展性)。
G18n需要将模型转换添加到I18n。
Padrino不是i18n库,它只是带有内置I18n的Sinatra框架。
Gettext是恕我直言的旧概念,格式非常丑陋,复数问题。无论如何,它在Ruby社区中并不流行。
答案 2 :(得分:5)
第一:
正如svenfuchs所写,I18n
是一个为许多翻译和国际化方法提供模块的框架
' gettext的'只是众多模块中的一个。
所以使用I18n
毫无疑问。
Rails应用程序的默认设置是使用I18n
和YAML后端,我理解你的问题的一部分,以便将后端与其他后端进行比较。
恕我直言,基于gettext
和YAML
的方法存在两个主要差异:
<强>的gettext 强>
gettext
的一个想法是,翻译应用程序不是单一事件,而是生命周期过程。
它的构建是为了支持这个实时循环。
gettext
旨在使用普通英语作为翻译的关键。因此,我们的想法是用英语编写应用程序并标记所有要翻译的文本,通常用_()
包装。
因此,应用程序源代码可以用英语轻松阅读。
然后程序扫描所有源代码并提取要翻译的文本并构建这些文本的存储库(.pot
文件)。
在下一步中,实时循环,存储库合并与现有翻译( .po 文件,一个用于标记每种目标语言)和新的或更改的项目。
成熟的编辑通过关注新的和更改的项目来支持翻译。此外,项目特定的词典可以支持部分自动翻译。
gettext
flat ,这意味着每个关键短语在翻译文件中只翻译一次。没有等级。但有背景。在翻译文件中,列出了关键短语的所有源代码位置。有权访问源代码的编辑器可以显示源代码和翻译(有些可以)。
最后,.po
文件被翻译为机器可读的快速访问表单(可以是 .mo ,经典标准,或数据库或json或......)
<强> YAML 强>
YAML另一方面是分层的,因此在不同的环境中很容易有翻译的变体
I18n使用此结构来支持scopes
,并在使用以点开头的键时使用当前文件路径作为范围。
没有信息,项目中使用了密钥(除非自动作用域,但密钥可以在其他地方明确使用)。
没有信息,是否有任何变化
除非您的IDE支持您,否则开发人员必须找到将密钥放入YAML的正确位置,并且搜索使用情况可能很麻烦。
在其他答案中说了很多。
<强>的I18n 强>
我故意说 YAML 而不是 I18n ,因为 I18n 是国际化(不仅仅是翻译)和 YAML的框架只是一个可能的后端 I18n中的多个支持不同于对vanilla 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进行翻译。
答案 3 :(得分:2)
安德烈回应我的回复r18n docs,基本上将其分解为一行:
R18n默认使用分层而非以英文为中心的YAML格式进行翻译。
从安德烈找到了这个幻灯片。它是用俄语写的,但它现在变得更有意义了(从第7到第9页,特别是i18n和r18n之间的明显区别):