user2320239
user2320239

Reputation: 1038

List all translation yml keys for a given language

so I have a translation file in my app as follows:

en:
  activemodel:
    attributes:
      post:
        title: Title
        message: Message
        tag: Tag
      user:
        name: Name
        email: Email

I'd like to get a list of all the key strings available so for this example I'd get the following:

'activemodel.attributes.post.title'
'activemodel.attributes.post.message'
'activemodel.attributes.post.tag'
'activemodel.attributes.user.name'
'activemodel.attributes.user.email'

I know I can get a hash of all translations with I18n.backend.send(:translations)[:en], but I'm not sure how to get each path.

Any help would be great thanks!

Upvotes: 2

Views: 1408

Answers (1)

ejdraper
ejdraper

Reputation: 549

You can process the translations hash returned by I18n.backend.send(:translations)[:en] with a recursive method:

def key_paths(key, hash_or_string)
  if hash_or_string.is_a?(Hash)
    hash_or_string.keys.map do |subkey|
      key_paths([key, subkey].compact.join("."), hash_or_string[subkey])
    end
  else
    key
  end
end

This recursively processes a hash, nesting keys for sub-hashes encountered to build up the paths you're looking for. When a sub-value isn't a hash (i.e. it's a string translation), it'll return the built-up key so far as it's reached the end of that nesting.

You could then wrap this up to find the paths for a given language with another helper method:

def lang_paths(lang)
  key_paths(nil, I18n.backend.send(:translations)[lang] || {}).flatten.sort
end

If you then run:

lang_paths(:en)

you'll get a sorted array of available translation paths back. If you run it for a language without translations, you'll get an empty array - you could raise an error in lang_paths for locales without translations if you wanted to handle that differently.

Hope that helps!

Upvotes: 5

Related Questions