34

I'm guessing that rails stores all the parsed translations yml files in a sort of array/hash. Is there a way to access this?

For example, if I've a file:

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

Could I do something like, I18n.translations_store[:en][:test_string] ? I could parse the yml file with YAML::load, but in my case I've splitted the yml files in subfolders for organization, and I'm pretty sure that rails already parsed them all.

Joel
  • 4,289
  • 1
  • 24
  • 40
Tiago
  • 2,808
  • 4
  • 31
  • 41

6 Answers6

65

You got to call a private method on the backend. This is how you get access:

translations = I18n.backend.send(:translations)
translations[:en][:test_string] # => "testing this"
balu
  • 3,449
  • 1
  • 22
  • 18
  • 29
    Note that `translations` will be empty if the backend isn't initialized, i.e. if you haven't used it for anything else yet. You will see this if you open up a new console and try to load the translations. You can get around it by doing `I18n.t(:foo); translations = I18n.backend.send(:translations)` (even if you don't have a `foo` translation). I'm sure there's a better way. – Henrik N Mar 14 '11 at 13:55
  • Thank you, @HenrikN, you save my day. – lifecoder Apr 08 '13 at 12:12
  • 13
    Thanks a lot. If the backend isn't initialized yet and the hash is empty, you can initialize it in this way: `I18n.backend.send(:init_translations) unless I18n.backend.initialized?` – Robin Sep 25 '13 at 20:14
  • 20
    You do not need to use private methods. Just call `I18n.t('.')` – 8xx8 Apr 22 '15 at 12:19
  • As an addition to @HenrikN comment, I'd say it can be initialized by calling `I18n.enforce_available_locales!(:fr)` where `:fr` is desirable locale. – sashaegorov Jan 12 '17 at 12:35
  • This is a dangerous way to follow. Ie. you won't be able to use this in Rake tasks since I18n hasn't initialized yet. Prefer Eric's answer. – msdundar May 25 '18 at 16:36
19

As per 8xx8's comment, a simpler version of:

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

is

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

This mitigates having to both preload the translations or specify the locale.

Eric H.
  • 6,058
  • 6
  • 35
  • 59
3

If you are using I18n::Fallbacks unfortunately you can't use I18n.t('.') as it just returns the contents current locale (eg. 'en-GB') and nothing from any of the fallback locales (eg 'en'). To get round this you can iterate over the fallbacks and use deep_merge! to combine them.

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

If you're doing this in a rake task, remember to include the enviroment, or otherwise it will not load your own locales which lives under 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
Dan Andreasson
  • 12,290
  • 5
  • 25
  • 28
2

The default I18n backend is I18n::Backend::Simple, which does not expose the translations to you. (I18.backend.translations is a protected method.)

This isn't generally a good idea, but if you really need this info and can't parse the file, you can extend the backend class.

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

You can then call I18n.backend.translations_store to get the parsed translations. You probably shouldn't rely on this as a long term strategy, but it gets you the information you need right now.

Dave Pirotte
  • 3,766
  • 19
  • 14
0

For the people wandering into this old question, there is a solution that does not require calling protected methods. Change your yml file as follows:

nl: &all

  ... translations here ...

  all:
    <<: *all

Now you can simply extract all translations using I18n.t("all"), which has the benefit of automatically initializing and reloading the translations in development mode (something which doesn't happen if you call the protected methods.)

Jacob
  • 76
  • 4