34

我猜 Rails 将所有已解析的翻译 yml 文件存储在一种数组/散列中。有没有办法访问这个?

例如,如果我有一个文件:

en:
  test_string: "testing this"
  warning: "This is just an example

我可以做类似 I18n.translations_store[:en][:test_string] 的事情吗?我可以使用 YAML::load 解析 yml 文件,但就我而言,我已将 yml 文件拆分为子文件夹以进行组织,而且我很确定 rails 已经将它们全部解析了。

4

6 回答 6

65

您必须在后端调用私有方法。这是您获得访问权限的方式:

translations = I18n.backend.send(:translations)
translations[:en][:test_string] # => "testing this"
于 2010-10-29T17:52:29.613 回答
20

根据 8xx8 的评论,一个更简单的版本:

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

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

这减轻了必须预先加载翻译或指定语言环境的情况。

于 2015-05-04T18:26:14.510 回答
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
于 2016-07-15T11:56:28.127 回答
2

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

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

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

然后,您可以调用I18n.backend.translations_store以获取已解析的翻译。您可能不应该将此作为长期策略,但它可以为您提供您现在需要的信息。

于 2010-09-29T16:40:18.003 回答
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
于 2016-01-15T08:55:41.077 回答
0

对于徘徊在这个老问题中的人们,有一个不需要调用受保护方法的解决方案。更改您的yml文件如下:

nl: &all

  ... translations here ...

  all:
    <<: *all

现在您可以使用 简单地提取所有翻译I18n.t("all"),这具有在开发模式下自动初始化和重新加载翻译的好处(如果您调用受保护的方法,则不会发生这种情况。)

于 2015-02-25T16:20:45.463 回答