]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/plugins/globalize2/lib/globalize/backend/chain.rb
Add Globalize2 so that we get some nice fall backs to other languages when a translat...
[rails.git] / vendor / plugins / globalize2 / lib / globalize / backend / chain.rb
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/chain.rb b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb
new file mode 100644 (file)
index 0000000..bb8679e
--- /dev/null
@@ -0,0 +1,102 @@
+module I18n
+  class << self
+    def chain_backends(*args)
+      self.backend = Globalize::Backend::Chain.new(*args)
+    end
+  end
+end
+  
+module Globalize  
+  module Backend
+    class Chain      
+      def initialize(*args)
+        add(*args) unless args.empty?
+      end
+      
+      # Change this to a) accept any number of backends and b) accept classes.
+      # When classes are passed instantiate them and add the instances as backends.
+      # Return the added backends from #add.
+      #
+      # Add an initialize method that accepts the same arguments and passes them
+      # to #add, so we could:
+      #   I18n.backend = Globalize::Backend::Chain.new(Globalize::Backend::Foo, Globalize::Backend::Bar)
+      #   Globalize::Backend::Chain.new(:foo, :bar)
+      #   Globalize.chain_backends :foo, :bar
+      def add(*backends)
+        backends.each do |backend|
+          backend = Globalize::Backend.const_get(backend.to_s.capitalize) if backend.is_a? Symbol
+          backend = backend.new if backend.is_a? Class
+          self.backends << backend
+        end
+      end
+      
+      def load_translations(*args)
+        backends.each{|backend| backend.load_translations(*args) }
+      end
+    
+      # For defaults:
+      # Never pass any default option to the backends but instead implement our own default
+      # mechanism (e.g. symbols as defaults would need to be passed to the whole chain to
+      # be translated).
+      #
+      # For namespace lookup: 
+      # Only return if the result is not a hash OR count is not present, otherwise merge them.
+      # So in effect the count variable would control whether we have a namespace lookup or a 
+      # pluralization going on.
+      #
+      # Exceptions:
+      # Make sure that we catch MissingTranslationData exceptions and raise
+      # one in the end when no translation was found at all.
+      #
+      # For bulk translation:
+      # If the key is an array we need to call #translate for each of the
+      # keys and collect the results.
+      
+      def translate(locale, key, options = {})
+        raise I18n::InvalidLocale.new(locale) if locale.nil?
+        return key.map{|k| translate locale, k, options } if key.is_a? Array
+        
+        default = options.delete(:default)
+        result = backends.inject({}) do |namespace, backend|
+          begin
+            translation = backend.translate(locale.to_sym, key, options) 
+            if namespace_lookup?(translation, options)
+              namespace.merge! translation
+            elsif translation
+              return translation 
+            end
+          rescue I18n::MissingTranslationData
+          end
+        end
+        result || default(locale, default, options) || raise(I18n::MissingTranslationData.new(locale, key, options))
+      end
+      
+      def localize(locale, object, format = :default)
+        backends.each do |backend|
+          result = backend.localize(locale, object, format) and return result
+        end
+      end
+    
+      protected
+        def backends
+          @backends ||= []
+        end
+        
+        def default(locale, default, options = {})
+          case default
+            when String then default
+            when Symbol then translate locale, default, options
+            when Array  then default.each do |obj| 
+              result = default(locale, obj, options.dup) and return result
+            end and nil
+          end
+        rescue I18n::MissingTranslationData
+          nil
+        end
+        
+        def namespace_lookup?(result, options)
+          result.is_a?(Hash) and not options.has_key?(:count)
+        end
+    end
+  end
+end
\ No newline at end of file