作为 Ruby 的新手,我正在探索现有的库来完成我通常在其他脚本语言中所做的事情,并且我对本地化库有点困惑,这些库可能可用于构建在 Sinatra/Sequel 之上的东西(Rails /AR 有点太固执己见了,不符合我的口味)。
现在,我在 这个 wiki 页面 中遇到了几个(i18n、r18n、GetText),并且显然有Padrino 中使用的额外库(基于 Rails 的 i18n 东西?);显然还有更多。
除了明显的(即 GetText mo/po 样式与 yml 文件)之外,我对这些选项可能有何不同感到有些困惑。维基百科在这方面没有指出太多,只是说它们存在;不是他们有什么不同。
更令人困惑的是,实际上每一份文档似乎都涵盖了其中的一个(通常是在 RoR 上下文中)。此外,仔细检查后,这些选项看起来并不完全不兼容——从某种意义上说,如果我正确理解这一点,它们可以在很大程度上理解彼此的文件。
这里有人能够对这些库进行快速、中肯的解释/概述,并概述它们之间的区别吗?如果您知道的话,一些关于性能的指示也将受到欢迎(除了来自 fast_gettext 文档的那些,考虑到我缺乏理解这些选项之间的差异,这没有什么意义)。
Being somewhat new to Ruby I'm exploring existing libraries to do what I'd normally do in other scripting languages, and I'm a bit stumped by the localization libraries that might be available for something built on top of Sinatra/Sequel (Rails/AR being a bit too opinionated to my taste).
Now, I ran into a couple (i18n, r18n, GetText) though this wiki page, and there apparently is an extra library used in Padrino (based on the i18n thing from Rails?); and apparently plenty more.
Except for the obvious (i.e. GetText mo/po style vs yml files), I'm somewhat confused as to how these options might be different. The wiki doesn't point to much in that respect except saying the that they exist; not how they're different.
Adding to this confusion is the fact that essentially every piece of documentation seems to cover a single one of them (and typically in a RoR context). Moreover, these options don't look entirely incompatible with one another on closer inspection -- in the sense that, if I understood this properly, they can understand each other's files to a large extent.
Might anyone here be able to give a quick and to the point explanation/overview of these libraries, and outline the difference between the them? Some pointers on performance would also be welcome, if you're aware of any (besides the ones from the fast_gettext docs, which made little sense considering my lack of understanding the difference between these options).
发布评论
评论(4)
在不了解 Ruby 中 i18n/l10n 库的一些历史的情况下,我可以看到这种情况是多么令人困惑。我可能应该就此写几句话,但现在我将尝试从我的角度进行概述:
Gettext 显然是这款游戏中最古老的玩家,它继承了其祖先的优点和缺点,这是为 C 主导的世界而发明的。它具有人们需要的大多数功能,附带一些其他人缺乏的工具支持(例如桌面 po 文件编辑器),并且在所谓的企业世界中被广泛接受。
Gettext 本身定义了一个 API 并且基本上有两个实现的库在 Ruby 世界中,传统的 Ruby Gettext 包由 正夫Mutoh 和 fast_gettext 宝石,作者: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 是随 Ruby on Rails 一起提供的官方解决方案,但它也可能是之一。
I18n gem 还使得非常容易扩展功能集并添加缓存、其他存储机制(如 Gettext po 文件、数据库表、键值存储;存储默认为纯 Ruby 文件和 YAML)等,并且附带 模块数量(但可以轻松制作、测试和集成外部或自定义模块) 。
对于 Ruby on Rails 使用的字符串,有 70 多种语言(区域设置)的翻译文件(这在其他项目中也很有用)由社区维护。
我无法透露太多关于 R18n 的信息,除了它是在 I18n 发布第一个版本后立即发明的,据我记得它起源于默布社区。它在俄罗斯红宝石世界中似乎相当强大,但我的所有这些断言可能都是错误的。
因此,除非您有充分的理由选择任何其他解决方案,否则我强烈建议您使用 I18n。
另一方面,这没有任何意义,因为我一直在领导这个项目 或多或少自它被发明以来。
我希望这有帮助。
[编辑]添加了各种参考文献的链接
I can see how this situation is confusing without knowing some of the history of i18n/l10n libraries in Ruby. I should probably write a few words up on that, but for now I'll try to give an overview from my perspective:
Gettext is obviously the oldest player in this game and it inherits both strengths and weaknesses from its ancestry which is being invented for a C dominated world. It has most features one needs, comes with some tools support that others lack (like desktop po file editors) and is widely accepted in the so called enterprise world.
Gettext as such defines an API and there are basically two libraries that implement it in the Ruby world, the traditional Ruby Gettext packages by Masao Mutoh and the fast_gettext gem by Michael Grosser.
Ruby Gettext is quite powerful and ships a lot of features that you may or may not need. The fast_gettext gem on the other hand focusses on raw speed and is implemented as a shiny, modern code-style Ruby library that is easily hackable and the author is a very smart and supportive person. Out of the two I'd personally strongly recommend fast_gettext.
The I18n gem is the result of the joint effort of various Ruby i18n/l10n solutions that existed a few years ago and that all strived to supersede Gettext for various reasons at that point of time. The resulting I18n API is basically covering the requirements and usecases of all the i18n/l10n solutions involved at that time, including the API of Gettext. So, today's Ruby I18n API is a superset of Gettext's API from the early 90s.
Today the I18n gem is the official solution that is shipped with Ruby on Rails, but it is also the probably most popular one in the Ruby world in general.
The I18n gem also makes it very easy to extend the featureset and add things like caching, other storage mechanisms (like Gettext po files, database tables, key-value stores; storage defaults to plain Ruby files and YAML) etc. and it ships with a number of modules for that (but external or custom modules can easily be crafted, tested and integrated).
There are translation files for 70+ languages (locales) for strings used by Ruby on Rails (which are useful in other projects, too) maintained by the community.
I can not tell much about R18n except that it was invented right after I18n hit its first release and as far as I remember it originated from the Merb community. It seems to be rather strong in the Russian Ruby world, but I might be wrong with all these assertions.
So, unless you have a very good reason to pick any other solution I'd strongly recommend using I18n.
Then on the other hand that means nothing because I've been leading this project more or less since it was invented.
I hope this helps.
[EDIT] added links to various references
I18n 是主流。
R18n 是一种替代方案,具有一些额外功能(模型翻译、语法糖)以及意识形态和架构方面的一些差异(通过强大的过滤器实现灵活的可扩展性)。
G18n 需要向 I18n 添加模型转换。
Padrino 不是一个 i18n 库,它只是内置 I18n 的 Sinatra 框架。
Gettext 是恕我直言的旧概念,格式非常丑陋,并且存在复数问题。不管怎样,它在 Ruby 社区并不流行。
I18n is a main stream.
R18n is a alternative with some extra features (model translations, syntax sugar) and some difference in ideology and architecture (flex extensibility by powerful filters).
G18n need to add model transtions to I18n.
Padrino is not a i18n library, it is just Sinatra framework with build-in I18n.
Gettext is IMHO old conception with very ugly format and problem with pluralization. Anyway, it isn’t popular in Ruby community.
第一:
正如 svenfuchs 所写,
I18n
是一个为许多翻译和国际化方法提供模块的框架。“gettext”只是众多模块之一。
所以使用
I18n
确实没有问题。Rails 应用程序的默认设置是将
I18n
与 YAML 后端结合使用,我理解您问题的一部分,以便将该后端与其他后端进行比较。恕我直言,基于
gettext
和YAML
的方法之间有两个主要区别:gettext
gettext
的一个想法> 是,翻译应用程序不是单一事件,而是一个生命周期过程。它是为了支持这个生命周期而构建的。
gettext
旨在使用简单的英语作为翻译的关键字。因此,我们的想法是用英语编写应用程序,并标记所有要翻译的文本,通常是用_()
将其包装起来。因此,应用程序源代码的英文版本很容易阅读。
然后,程序扫描所有源代码并提取要翻译的文本,并构建这些文本的存储库(
.pot
文件)。在下一步中,生命周期即将到来,存储库将与现有翻译(.po 文件,每种目标语言一个)合并 )并标记新的或更改的项目。
成熟的编辑通过关注新的和更改的项目来支持译者。此外,项目特定词典可以支持部分自动翻译。
gettext
是扁平,这意味着每个关键短语在翻译文件中只翻译一次。没有等级之分。但有上下文。在翻译文件中,列出了关键短语的所有源代码位置。有权访问源代码的编辑器可以显示源代码以及翻译(有些编辑器确实这样做)。最后,
.po
文件被转换为机器可读的快速访问表单(可以是.mo,经典标准,或者数据库或 json 或...)YAML< /strong>
YAML 是分层的,因此在不同的上下文中很容易出现不同的翻译。
I18n 使用此结构来支持
范围
,并在使用以点开头的键时使用当前文件路径作为范围。没有信息表明项目中使用了某个密钥(除非是自动作用域,但该密钥可能会在其他地方明确使用)。
暂无信息,是否有变化。
除非您的 IDE 支持您,否则开发人员必须在 YAML 中找到放置密钥的正确位置,并且搜索用法可能会很麻烦。
其他答案里说了很多。
I18n
我故意说YAML而不是I18n,因为I18n是一个国际化框架(不仅仅是翻译), YAML 只是一种可能的后端。
I18n 中的复数支持与普通 gettext 的复数支持不同。我没有经验他们如何合作。
示例
带有位置参数的 gettext:
翻译是文本文件,但 PO 编辑器提供 GUI:
YAML 带有参数:
源
翻译
从
到
结论
YAML 更容易上手,特别是如果您有 IDE 支持的话。
Vanilla RAILS 内置了它。
这不是母语。第一个翻译可以是任何语言。
随着项目的不断增长和多种语言的出现,我的 YAML 文件往往会重复(相同的翻译分散在层次结构中)并跟踪更改,因此新的翻译很麻烦。
gettext 需要额外的工具链,因此设置更加困难。
它支持开发应用程序的持续翻译的整个生命周期。
它基于英文源代码。
我通常使用两者最好的部分,使用 YAML 进行国际化(数字和日期格式,也许模型名称?)并使用 gettext 进行翻译。
First:
as svenfuchs wrote,
I18n
is a framework that provides modules for many translation and internationalisation approaches.'gettext' is just one of many modules.
So there is really no question to use
I18n
.The default setup of a Rails application is to use
I18n
with the YAML backend and I understand part of your question to compare that backend with other ones.IMHO there are two major differences between the
gettext
andYAML
based approaches:gettext
One idea of
gettext
is, that translating an app is not a singular event but a life cycle process.It is build to support this live cycle.
gettext
is designed to use plain english as the keys for the translations. So the idea is to write the app in english and mark all text that is to be translated, typically by wrapping it with_()
.As a result, the app source code is easily readable in english.
Then a programm scans all source code and extracts the textes to be translated and builds a repository (the
.pot
file) of these textes.In the next step, and here comes the live cycle, the repository is merged with existing translations (.po files, one for each target language) and new or changed items are marked.
Mature editors support the translators by focusing on the new and changed items. Additionally project specific dictionaries can support partial automatic translations.
gettext
is flat, meaning that each key phrase is translates exactly once in the translation files. There is no hierarchy. But there is context. In the translation files, all the source code positions of a key phrase are listed. An editor with access to the source code can display the source along with the translation (and some do).Finally,
.po
files are translated to machine readable fast access forms (can be .mo, the classic standard, or a database or json or …)YAML
YAML an the other hand is hierarchical so it’s easy to have variations of translations in different contexts.
I18n uses this structure to support
scopes
and uses the current file path as scope when using keys starting with a dot.There is no information, where a key is used in the project (well unless auto scoped, but the key may be used in other places explicitly).
There is no information, whether there are any changes.
Unless your IDE supports you, the developer has to find the right place to put a key in the YAML and searching the usage can be cumbersome.
A lot more is said in the other answers.
I18n
I intentionally said YAML and not I18n, because I18n is a framework for internationalization (not only translation), and YAML is only one possible backend.
Plural support in I18n differs from plural support of vanilla gettext. I don’t have experience how they cooperate.
Examples
gettext with positional parameters:
translations are text files, but PO-Editors provide GUIs:
YAML with parameters:
Source
translation
from
to
Conclusion
YAML is much easier to start with, especially if you have support by an IDE.
Vanilla RAILS has it built in.
The is no native language. The first translation can be any language.
With growing projects and multiple laguages, my YAML files tend to repetition (same translation scattered over the hierarchy) and tracing of changes and therefore new translations is cumbersome.
gettext needs an extra toolchain and therefore a more difficult setup.
It supports the whole life cycle of continous translation of developing apps.
It is based on english source code.
I usually use the best parts of both, using YAML for internationalisation (number and date format, maybe model names?) and gettext for translation.
Andrey 的回应让我回到 r18n 文档,它基本上将其分解为一行:
从安德烈那里找到了这张幻灯片。它是俄语的,但现在更有意义了(幻灯片 7 到 9 特别是 i18n 和 r18n 之间的明确差异):
http://www.slideshare.net/iskin/r18n
Andrey's response as to point me back to the r18n docs, which basically break it down to a single line:
Found this slideshare from Andrey. It's in Russian, but it's making a lot more sense now (slides 7 to 9 in particular clear-cut differences between i18n and r18n):
http://www.slideshare.net/iskin/r18n