I18n: How to check if a translation key/value pairs is missing?

17,426

Solution 1

I just had the same question and I want to compute an automatic string in case the translation is missing. If I use the :default option I have to compute the automatic string every time even when the translation is not missing. So I searched for another solution.

You can add the option :raise => true or use I18n.translate! instead of I18n.translate. If no translation can be found an exception is raised.

begin
  I18n.translate!('this.key.should.be.translated', :raise => true) 
rescue I18n::MissingTranslationData
  do_some_resource_eating_text_generation_here
end

Solution 2

You could pass a :default parameter to I18n.t:

I18n.t :missing, :default => 'Not here'
# => 'Not here'

You can read more about it here.

Solution 3

I don't know how to this at runtime but you can use rake to find it out. You'll have create your own rake task for that. Here's one:

namespace :i18n do
  desc "Find and list translation keys that do not exist in all locales"
  task :missing_keys => :environment do

    def collect_keys(scope, translations)
      full_keys = []
      translations.to_a.each do |key, translations|
        new_scope = scope.dup << key
        if translations.is_a?(Hash)
          full_keys += collect_keys(new_scope, translations)
        else
          full_keys << new_scope.join('.')
        end
      end
      return full_keys
    end

    # Make sure we've loaded the translations
    I18n.backend.send(:init_translations)
    puts "#{I18n.available_locales.size} #{I18n.available_locales.size == 1 ? 'locale' : 'locales'} available: #{I18n.available_locales.to_sentence}"

    # Get all keys from all locales
    all_keys = I18n.backend.send(:translations).collect do |check_locale, translations|
      collect_keys([], translations).sort
    end.flatten.uniq
    puts "#{all_keys.size} #{all_keys.size == 1 ? 'unique key' : 'unique keys'} found."

    missing_keys = {}
    all_keys.each do |key|

      I18n.available_locales.each do |locale|
        I18n.locale = locale
        begin
          result = I18n.translate(key, :raise => true)
        rescue I18n::MissingInterpolationArgument
          # noop
        rescue I18n::MissingTranslationData
          if missing_keys[key]
            missing_keys[key] << locale
          else
            missing_keys[key] = [locale]
          end
        end
      end
    end
    puts "#{missing_keys.size} #{missing_keys.size == 1 ? 'key is missing' : 'keys are missing'} from one or more locales:"
    missing_keys.keys.sort.each do |key|
      puts "'#{key}': Missing from #{missing_keys[key].join(', ')}"
    end
  end
end

put the given in a .rake file in your lib/tasks directory and execute:

rake i18n:missing_keys 

Information source is here and code on github here.

Share:
17,426

Related videos on Youtube

user12882
Author by

user12882

Updated on June 04, 2022

Comments

  • user12882
    user12882 almost 2 years

    I am using Ruby on Rails 3.1.0 and the I18n gem. I (am implementing a plugin and) I would like to check at runtime if the I18n is missing a translation key/value pairs and, if so, to use a custom string. That is, I have:

    validates :link_url,
      :format     => {
        :with => REGEX,
        :message  => I18n.t(
          'custom_invalid_format',
          :scope => 'activerecord.errors.messages'
      )
    }
    

    If in the .yml file there is not the following code

    activerecord:
      errors:
        messages:
          custom_invalid_format: This is the test error message 1
    

    I would like to use the This is the test error message 2. Is it possible? If so, how can I make that?

    BTW: For performance reasons, is it advisable to check at runtime if the translation key/value pairs is present?

  • user12882
    user12882 over 12 years
    Your answer doesn't not accomplish what I am looking for, but thank you anyway. Waiting for another answer...
  • user12882
    user12882 about 12 years
    Thank you for your answer, but that isn't what I am looking for (re-read the question, please).
  • Matstar
    Matstar over 11 years
    If you do something like this, note that translation keys may not match up exactly due to different pluralization rules (and so different keys). Fixed here: gist.github.com/2994129 (via my henrik.nyh.se/2012/07/rails-i18n-tips)