如何从Rails I18n的yml文件中检索所有翻译

36
我猜Rails会将所有解析过的翻译yml文件存储在一种数组/哈希表中。有没有一种方法可以访问它?
例如,如果我有一个文件:
en:
  test_string: "testing this"
  warning: "This is just an example

我能做类似这样的事情吗,I18n.translations_store[:en][:test_string]? 我可以使用YAML :: load解析yml文件,但在我的情况下,我已将yml文件拆分为子文件夹进行组织,并且我相信rails已经解析了它们。

6个回答

68

你需要在后端调用一个私有方法来获取访问权限,以下是具体步骤:

translations = I18n.backend.send(:translations)
translations[:en][:test_string] # => "testing this"

32
请注意,如果后端未初始化,即您尚未在其他任何地方使用它,则“translations”将为空。如果您打开新控制台并尝试加载翻译,您将看到这一点。您可以通过执行“I18n.t(:foo); translations = I18n.backend.send(:translations)”(即使您没有“foo”翻译)来避免这种情况。我相信有更好的方法。 - Henrik N
14
非常感谢。如果后端尚未初始化且哈希为空,则可以通过以下方式进行初始化:I18n.backend.send(:init_translations) unless I18n.backend.initialized? - Robin
21
您不需要使用私有方法,只需调用I18n.t('.') - 8xx8
作为对 @HenrikN 评论的补充,我认为可以通过调用 I18n.enforce_available_locales!(:fr) 进行初始化,其中 :fr 是所需的语言环境。 - sashaegorov
这是一种危险的方式。也就是说,您将无法在Rake任务中使用它,因为I18n尚未初始化。建议使用Eric的答案。 - msdundar

20

根据8xx8的评论,以下是更简单的版本:

I18n.t(:foo)
I18n.backend.send(:translations)[:en][:test_string]

是什么

I18n.t(".")[:test_string]

这可以减轻预加载翻译或指定语言环境的压力。


1
这对我来说是最好的解决方案:I18n.t(".")。谢谢。 - jordelver

3
如果您使用了 I18n::Fallbacks,那么不幸的是您不能使用 I18n.t('.'),因为它只返回当前语言环境(例如 'en-GB')的内容,而没有任何后备语言环境(例如 'en')的内容。要解决这个问题,您可以遍历后备语言环境并使用 deep_merge! 来合并它们。
module I18n
  class << self
    def all
      fallbacks[I18n.locale].reverse.reduce({}) do |translations, fallback|
        translations.deep_merge!(backend.translate(fallback, '.'))
      end
    end
  end
end

2

如果您在Rake任务中进行此操作,请记得包含环境配置,否则它将无法加载位于config/locales/下的本地化信息。

require "./config/environment.rb" # Do not forget this

namespace :i18n do
  desc "Import I18n to I18n_active_record"
  task :setup do
    I18n.t(:foo)
    translations = I18n.backend.send(:translations)
  end
end

2

默认的I18n后端是I18n::Backend::Simple,它不会向您公开翻译内容(I18.backend.translations是受保护的方法)。

通常情况下这不是一个好主意,但如果您确实需要此信息且无法解析文件,则可以扩展后端类。

class I18n::Backend::Simple
  def translations_store
    translations
  end
end

您可以调用I18n.backend.translations_store来获取已解析的翻译。您可能不应该依赖此作为长期策略,但它可以让您立即获得所需信息。


2

对于那些进入这个旧问题的人,有一种解决方案不需要调用受保护的方法。请按照以下方式更改您的 yml 文件:

nl: &all

  ... translations here ...

  all:
    <<: *all

现在,您可以使用I18n.t("all")来提取所有的翻译。这样做的好处是,在开发模式下自动初始化和重新加载翻译(如果您调用受保护的方法,则不会发生这种情况)。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接