【问题标题】:How to retrieve all translations from yml files in Rails I18n如何从 Rails I18n 中的 yml 文件中检索所有翻译
【发布时间】:2011-04-18 22:11:11
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: ruby-on-rails internationalization yaml rails-i18n


    【解决方案1】:

    如果你使用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
      

      【讨论】:

        【解决方案3】:

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

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

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

        这减少了预加载翻译或指定语言环境的麻烦。

        【讨论】:

        • 这对我来说是最好的解决方案I18n.t(".")。谢谢。
        【解决方案4】:

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

        nl: &all
        
          ... translations here ...
        
          all:
            <<: *all
        

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

          • 注意translations 如果后端未初始化,则为空,也就是说,如果您还没有将它用于其他任何事情。如果您打开一个新控制台并尝试加载翻译,您将看到这一点。你可以通过I18n.t(:foo); translations = I18n.backend.send(:translations) 来解决它(即使你没有foo 翻译)。我确信有更好的方法。
          • 谢谢你,@HenrikN,你拯救了我的一天。
          • 非常感谢。如果后端还没有初始化,hash为空,可以这样初始化:I18n.backend.send(:init_translations) unless I18n.backend.initialized?
          • 您不需要使用私有方法。只需致电I18n.t('.')
          • 作为@HenrikN 评论的补充,我想说它可以通过调用I18n.enforce_available_locales!(:fr) 来初始化,其中:fr 是理想的语言环境。
          【解决方案6】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-09-23
            相关资源
            最近更新 更多