1 # I18n locale fallbacks are useful when you want your application to use
2 # translations from other locales when translations for the current locale are
3 # missing. E.g. you might want to use :en translations when translations in
4 # your applications main locale :de are missing.
6 # To enable locale fallbacks you can simply include the Fallbacks module to
7 # the Simple backend - or whatever other backend you are using:
9 # I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
14 # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+.
16 @@fallbacks ||= I18n::Locale::Fallbacks.new
19 # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation.
20 def fallbacks=(fallbacks)
21 @@fallbacks = fallbacks
27 # Overwrites the Base backend translate method so that it will try each
28 # locale given by I18n.fallbacks for the given locale. E.g. for the
29 # locale :"de-DE" it might try the locales :"de-DE", :de and :en
30 # (depends on the fallbacks implementation) until it finds a result with
31 # the given options. If it does not find any result for any of the
32 # locales it will then throw MissingTranslation as usual.
34 # The default option takes precedence over fallback locales only when
35 # it's a Symbol. When the default contains a String, Proc or Hash
36 # it is evaluated last after all the fallback locales have been tried.
37 def translate(locale, key, options = {})
38 return super if options[:fallback]
39 default = extract_non_symbol_default!(options) if options[:default]
41 options[:fallback] = true
42 I18n.fallbacks[locale].each do |fallback|
44 result = super(fallback, key, options)
45 return result unless result.nil?
48 options.delete(:fallback)
50 return super(locale, nil, options.merge(:default => default)) if default
51 throw(:exception, I18n::MissingTranslation.new(locale, key, options))
54 def extract_non_symbol_default!(options)
55 defaults = [options[:default]].flatten
56 first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)}
57 if first_non_symbol_default
58 options[:default] = defaults[0, defaults.index(first_non_symbol_default)]
60 return first_non_symbol_default