3 # Backend that chains multiple other backends and checks each of them when
4 # a translation needs to be looked up. This is useful when you want to use
5 # standard translations with a Simple backend but store custom application
6 # translations in a database or other backends.
8 # To use the Chain backend instantiate it and set it to the I18n module.
9 # You can add chained backends through the initializer or backends
12 # # preserves the existing Simple backend set to I18n.backend
13 # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
15 # The implementation assumes that all backends added to the Chain implement
16 # a lookup method with the same API as Simple backend does.
21 attr_accessor :backends
23 def initialize(*backends)
24 self.backends = backends
28 backends.each { |backend| backend.reload! }
31 def store_translations(locale, data, options = {})
32 backends.first.store_translations(locale, data, options)
36 backends.map { |backend| backend.available_locales }.flatten.uniq
39 def translate(locale, key, default_options = {})
41 options = default_options.except(:default)
43 backends.each do |backend|
45 options = default_options if backend == backends.last
46 translation = backend.translate(locale, key, options)
47 if namespace_lookup?(translation, options)
49 namespace.merge!(translation)
50 elsif !translation.nil?
56 return namespace if namespace
57 throw(:exception, I18n::MissingTranslation.new(locale, key, options))
60 def localize(locale, object, format = :default, options = {})
61 backends.each do |backend|
63 result = backend.localize(locale, object, format, options) and return result
66 throw(:exception, I18n::MissingTranslation.new(locale, format, options))
70 def namespace_lookup?(result, options)
71 result.is_a?(Hash) && !options.has_key?(:count)
75 include Implementation