【问题标题】:Ruby localization: i18n, g18n, gettext, padrino... - what's the difference?Ruby 本地化:i18n、g18n、gettext、padrino... - 有什么区别?
【发布时间】:2011-09-19 11:50:55
【问题描述】:

我对 Ruby 有点陌生,我正在探索现有的库来做我通常在其他脚本语言中做的事情,我有点难过本地化库,这些本地化库可能可用于构建在 Sinatra 之上的东西/续集(Rails/AR 对我来说有点太固执了)。

现在,我在this wiki page 中遇到了一对(i18n、r18n、GetText),而且显然在 Padrino 中使用了一个额外的库(基于 Rails 的 i18n 东西?);显然还有更多。

除了显而易见的(即 GetText mo/po 样式与 yml 文件)之外,我对这些选项可能有何不同感到有些困惑。 wiki 在这方面并没有指出太多,只是说它们存在。不是他们有什么不同。

更令人困惑的是,实际上每一份文档似乎都涵盖了其中一个(通常在 RoR 上下文中)。此外,仔细观察,这些选项看起来并不完全不兼容——从某种意义上说,如果我正确理解这一点,它们可以在很大程度上理解彼此的文件。

这里的任何人都可以对这些库进行快速而中肯的解释/概述,并概述它们之间的区别吗?如果您知道任何关于性能的指示,也将受到欢迎(除了 fast_gettext 文档中的那些,考虑到我缺乏理解这些选项之间的区别,这毫无意义)。

【问题讨论】:

    标签: ruby localization internationalization sinatra padrino


    【解决方案1】:

    Andrey 的回复让我回到 r18n docs,它基本上将其分解为一行:

    R18n 默认使用分层而非以英语为中心的 YAML 格式进行翻译。

    从 Andrey 那里找到这个幻灯片。它是俄语的,但现在更有意义(幻灯片 7 到 9,特别是 i18n 和 r18n 之间的明显区别):

    http://www.slideshare.net/iskin/r18n

    【讨论】:

    • 确实看起来像。 Sven 的回答非常丰富,但遗憾的是它没有强调 i18n 和 r18n 的不同之处,所以我想我会强调我最终是如何得到它的。 :-)
    【解决方案2】:

    I18n 是主流。

    R18n 是一种替代方案,具有一些额外的功能(模型翻译、语法糖)以及在意识形态和架构上的一些差异(通过强大的过滤器实现灵活扩展)。

    G18n 需要将模型转换添加到 I18n。

    Padrino 不是 i18n 库,它只是内置 I18n 的 Sinatra 框架。

    Gettext 是恕我直言的旧概念,格式非常丑陋,并且存在复数问题。无论如何,它在 Ruby 社区中并不流行。

    【讨论】:

    • 你们太棒了,能在这里停下来回答。太感谢了。 :-)
    【解决方案3】:

    在不了解 Ruby 中 i18n/l10n 库的一些历史的情况下,我可以看到这种情况令人困惑。我可能应该写几句话,但现在我将尝试从我的角度给出一个概述:

    Gettext 显然是这个游戏中最年长的玩家,它继承了它的祖先的优点和缺点,这是为 C 主宰的世界而发明的。它具有大多数人需要的功能,附带一些其他人缺乏的工具支持(如桌面 po 文件编辑器),并且在所谓的企业世界中被广泛接受。

    Gettext 本身定义了一个 API,并且在 Ruby 世界中基本上有两个库实现它,Masao Mutoh 的传统 Ruby Gettext 包和 Michael Grosserfast_gettext gem。

    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(但可以轻松地制作、测试和集成外部或自定义模块)。

    社区维护了 70+ languages(语言环境)的翻译文件,用于 Ruby on Rails(在其他项目中也很有用)使用的字符串。

    关于R18n,我不能说太多,除了它是在 I18n 发布第一个版本之后发明的,据我所知,它起源于 Merb 社区。它在俄罗斯 Ruby 世界中似乎相当强大,但我可能对所有这些断言都错了。

    因此,除非您有充分的理由选择任何其他解决方案,否则我强烈建议您使用 I18n。

    另一方面,这意味着什么,因为 I've been leading this project 或多或少自它被发明以来。

    我希望这会有所帮助。

    [EDIT] 添加了指向各种参考资料的链接

    【讨论】:

    • 你们太棒了,能在这里停下来回答。太感谢了。 :-)
    • 这是维基资料 Sven :)
    • @svenfuchs,计划为我所有的 Rails 应用程序实现你的 gem。您的视频添加了缺失的部分。现在我们将使用 po 文件,因为这将是为每个网站使用几个人进行协作的最简单方法。关于视频和这篇文章的大量信息。
    【解决方案4】:

    第一:
    正如 svenfuchs 所写,I18n 是一个为许多翻译和国际化方法提供模块的框架。
    'gettext' 只是众多模块之一。

    所以使用I18n确实没有问题。

    Rails 应用程序的默认设置是将 I18n 与 YAML 后端一起使用,我理解您的部分问题是将该后端与其他后端进行比较。


    恕我直言,基于 gettextYAML 的方法有两个主要区别:

    • 生命周期支持
    • 层次结构

    获取文本

    gettext 的一个想法是,翻译应用程序不是一个单一的事件,而是一个生命周期过程。
    它是为支持这个生命周期而构建的。

    gettext 旨在使用简单的英语作为翻译的键。所以想法是用英语编写应用程序并标记所有要翻译的文本,通常用_()包装。
    因此,应用程序源代码很容易用英文阅读。

    然后一个程序扫描所有源代码并提取要翻译的文本并构建这些文本的存储库.pot 文件)。

    在下一步中,生命周期来了,存储库与现有翻译(.po 文件,一个用于每个目标语言)和新的或更改的项目都被标记。

    成熟的编辑通过关注新的和更改的项目来支持翻译。此外,项目特定的词典可以支持部分自动翻译。

    gettextflat,这意味着每个关键短语在翻译文件中只翻译一次。没有等级制度。但有上下文。在翻译文件中,列出了一个关键短语的所有源代码位置。有权访问源代码的编辑器可以显示源代码以及翻译(有些人会这样做)。

    最后,.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 进行翻译。

    【讨论】:

    • 我使用 gettext() 的主要问题是:程序是用英文编写的,然后翻译英文字符串。这意味着一个英文字符串的翻译总是相同的。但这不是自然语言的工作方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 2019-11-18
    • 2010-09-06
    • 2010-11-17
    • 2010-09-14
    相关资源
    最近更新 更多