]> git.openstreetmap.org Git - rails.git/blob - vendor/plugins/globalize2/lib/globalize/backend/chain.rb
* GPX view/edit translations
[rails.git] / vendor / plugins / globalize2 / lib / globalize / backend / chain.rb
1 module I18n
2   class << self
3     def chain_backends(*args)
4       self.backend = Globalize::Backend::Chain.new(*args)
5     end
6   end
7 end
8   
9 module Globalize  
10   module Backend
11     class Chain      
12       def initialize(*args)
13         add(*args) unless args.empty?
14       end
15       
16       # Change this to a) accept any number of backends and b) accept classes.
17       # When classes are passed instantiate them and add the instances as backends.
18       # Return the added backends from #add.
19       #
20       # Add an initialize method that accepts the same arguments and passes them
21       # to #add, so we could:
22       #   I18n.backend = Globalize::Backend::Chain.new(Globalize::Backend::Foo, Globalize::Backend::Bar)
23       #   Globalize::Backend::Chain.new(:foo, :bar)
24       #   Globalize.chain_backends :foo, :bar
25       def add(*backends)
26         backends.each do |backend|
27           backend = Globalize::Backend.const_get(backend.to_s.capitalize) if backend.is_a? Symbol
28           backend = backend.new if backend.is_a? Class
29           self.backends << backend
30         end
31       end
32       
33       def load_translations(*args)
34         backends.each{|backend| backend.load_translations(*args) }
35       end
36     
37       # For defaults:
38       # Never pass any default option to the backends but instead implement our own default
39       # mechanism (e.g. symbols as defaults would need to be passed to the whole chain to
40       # be translated).
41       #
42       # For namespace lookup: 
43       # Only return if the result is not a hash OR count is not present, otherwise merge them.
44       # So in effect the count variable would control whether we have a namespace lookup or a 
45       # pluralization going on.
46       #
47       # Exceptions:
48       # Make sure that we catch MissingTranslationData exceptions and raise
49       # one in the end when no translation was found at all.
50       #
51       # For bulk translation:
52       # If the key is an array we need to call #translate for each of the
53       # keys and collect the results.
54       
55       def translate(locale, key, options = {})
56         raise I18n::InvalidLocale.new(locale) if locale.nil?
57         return key.map{|k| translate locale, k, options } if key.is_a? Array
58         
59         default = options.delete(:default)
60         result = backends.inject({}) do |namespace, backend|
61           begin
62             translation = backend.translate(locale.to_sym, key, options) 
63             if namespace_lookup?(translation, options)
64               namespace.merge! translation
65             elsif translation
66               return translation 
67             end
68           rescue I18n::MissingTranslationData
69           end
70         end
71         result || default(locale, default, options) || raise(I18n::MissingTranslationData.new(locale, key, options))
72       end
73       
74       def localize(locale, object, format = :default)
75         backends.each do |backend|
76           result = backend.localize(locale, object, format) and return result
77         end
78       end
79     
80       protected
81         def backends
82           @backends ||= []
83         end
84         
85         def default(locale, default, options = {})
86           case default
87             when String then default
88             when Symbol then translate locale, default, options
89             when Array  then default.each do |obj| 
90               result = default(locale, obj, options.dup) and return result
91             end and nil
92           end
93         rescue I18n::MissingTranslationData
94           nil
95         end
96         
97         def namespace_lookup?(result, options)
98           result.is_a?(Hash) and not options.has_key?(:count)
99         end
100     end
101   end
102 end