5a0c59b59b9a2416771327c1b0a19e46c8547005
[packages/precise/mcollective.git] / lib / mcollective / vendor / i18n / lib / i18n / backend / chain.rb
1 module I18n
2   module Backend
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.
7     #
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
10     # accessor:
11     #
12     #   # preserves the existing Simple backend set to I18n.backend
13     #   I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
14     #
15     # The implementation assumes that all backends added to the Chain implement
16     # a lookup method with the same API as Simple backend does.
17     class Chain
18       module Implementation
19         include Base
20
21         attr_accessor :backends
22
23         def initialize(*backends)
24           self.backends = backends
25         end
26
27         def reload!
28           backends.each { |backend| backend.reload! }
29         end
30
31         def store_translations(locale, data, options = {})
32           backends.first.store_translations(locale, data, options)
33         end
34
35         def available_locales
36           backends.map { |backend| backend.available_locales }.flatten.uniq
37         end
38
39         def translate(locale, key, default_options = {})
40           namespace = nil
41           options = default_options.except(:default)
42
43           backends.each do |backend|
44             catch(:exception) do
45               options = default_options if backend == backends.last
46               translation = backend.translate(locale, key, options)
47               if namespace_lookup?(translation, options)
48                 namespace ||= {}
49                 namespace.merge!(translation)
50               elsif !translation.nil?
51                 return translation
52               end
53             end
54           end
55
56           return namespace if namespace
57           throw(:exception, I18n::MissingTranslation.new(locale, key, options))
58         end
59
60         def localize(locale, object, format = :default, options = {})
61           backends.each do |backend|
62             catch(:exception) do
63               result = backend.localize(locale, object, format, options) and return result
64             end
65           end
66           throw(:exception, I18n::MissingTranslation.new(locale, format, options))
67         end
68
69         protected
70           def namespace_lookup?(result, options)
71             result.is_a?(Hash) && !options.has_key?(:count)
72           end
73       end
74
75       include Implementation
76     end
77   end
78 end