I18n: How to check if a translation key/value pairs is missing?
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.
Related videos on Youtube
user12882
Updated on June 04, 2022Comments
-
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 codeactiverecord: 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?
-
JayWould something like this be of use? stackoverflow.com/questions/4223806/…
-
-
user12882 over 12 yearsYour answer doesn't not accomplish what I am looking for, but thank you anyway. Waiting for another answer...
-
user12882 about 12 yearsThank you for your answer, but that isn't what I am looking for (re-read the question, please).
-
Matstar over 11 yearsIf 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)