From 36a2f1f3c085dd81171cf7d8220770d4ff921ab3 Mon Sep 17 00:00:00 2001 From: hukl Date: Sat, 7 Feb 2009 15:50:40 +0100 Subject: added globalize2 plugin as well as some modifications which use the new translation facilities. backend mostly. --- .../globalize2/lib/globalize/backend/chain.rb | 102 +++++++++++++++++++++ .../lib/globalize/backend/pluralizing.rb | 37 ++++++++ .../globalize2/lib/globalize/backend/static.rb | 59 ++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 vendor/plugins/globalize2/lib/globalize/backend/chain.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/backend/static.rb (limited to 'vendor/plugins/globalize2/lib/globalize/backend') diff --git a/vendor/plugins/globalize2/lib/globalize/backend/chain.rb b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb new file mode 100644 index 00000000..bb8679ec --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb @@ -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 diff --git a/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb b/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb new file mode 100644 index 00000000..80016f20 --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb @@ -0,0 +1,37 @@ +require 'i18n/backend/simple' + +module Globalize + module Backend + class Pluralizing < I18n::Backend::Simple + def pluralize(locale, entry, count) + return entry unless entry.is_a?(Hash) and count + key = :zero if count == 0 && entry.has_key?(:zero) + key ||= pluralizer(locale).call(count) + raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) + translation entry[key], :plural_key => key + end + + def add_pluralizer(locale, pluralizer) + pluralizers[locale.to_sym] = pluralizer + end + + def pluralizer(locale) + pluralizers[locale.to_sym] || default_pluralizer + end + + protected + def default_pluralizer + pluralizers[:en] + end + + def pluralizers + @pluralizers ||= { :en => lambda{|n| n == 1 ? :one : :other } } + end + + # Overwrite this method to return something other than a String + def translation(string, attributes) + string + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/globalize/backend/static.rb b/vendor/plugins/globalize2/lib/globalize/backend/static.rb new file mode 100644 index 00000000..3903517c --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/backend/static.rb @@ -0,0 +1,59 @@ +require 'globalize/backend/pluralizing' +require 'globalize/locale/fallbacks' +require 'globalize/translation' + +module Globalize + module Backend + class Static < Pluralizing + def initialize(*args) + add(*args) unless args.empty? + end + + def translate(locale, key, options = {}) + result, default, fallback = nil, options.delete(:default), nil + I18n.fallbacks[locale].each do |fallback| + begin + result = super(fallback, key, options) and break + rescue I18n::MissingTranslationData + end + end + result ||= default locale, default, options + + attrs = {:requested_locale => locale, :locale => fallback, :key => key, :options => options} + translation(result, attrs) || raise(I18n::MissingTranslationData.new(locale, key, options)) + end + + protected + + alias :orig_interpolate :interpolate unless method_defined? :orig_interpolate + def interpolate(locale, string, values = {}) + result = orig_interpolate(locale, string, values) + translation = translation(string) + translation.nil? ? result : translation.replace(result) + end + + def translation(result, meta = nil) + return unless result + + case result + when Numeric + result + when String + result = Translation::Static.new(result) unless result.is_a? Translation::Static + result.set_meta meta + result + when Hash + Hash[*result.map do |key, value| + [key, translation(value, meta)] + end.flatten] + when Array + result.map do |value| + translation(value, meta) + end + else + raise "unexpected translation type: #{result.inspect}" + end + end + end + end +end \ No newline at end of file -- cgit v1.3