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 +++++++++++ .../i18n/missing_translations_log_handler.rb | 41 ++++++++ .../plugins/globalize2/lib/globalize/load_path.rb | 63 ++++++++++++ .../globalize2/lib/globalize/locale/fallbacks.rb | 63 ++++++++++++ .../lib/globalize/locale/language_tag.rb | 81 +++++++++++++++ .../lib/globalize/model/active_record.rb | 38 +++++++ .../lib/globalize/model/active_record/adapter.rb | 77 ++++++++++++++ .../globalize/model/active_record/translated.rb | 111 +++++++++++++++++++++ .../globalize2/lib/globalize/translation.rb | 32 ++++++ vendor/plugins/globalize2/lib/locale/root.yml | 3 + .../globalize2/lib/rails_edge_load_path_patch.rb | 40 ++++++++ 13 files changed, 747 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 create mode 100644 vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/load_path.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/model/active_record.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb create mode 100644 vendor/plugins/globalize2/lib/globalize/translation.rb create mode 100644 vendor/plugins/globalize2/lib/locale/root.yml create mode 100644 vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb (limited to 'vendor/plugins/globalize2/lib') 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 diff --git a/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb new file mode 100644 index 00000000..3f06ac24 --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb @@ -0,0 +1,41 @@ +# A simple exception handler that behaves like the default exception handler +# but additionally logs missing translations to a given log. +# +# Useful for identifying missing translations during testing. +# +# E.g. +# +# require 'globalize/i18n/missing_translations_log_handler +# I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER +# I18n.exception_handler = :missing_translations_log_handler +# +# To set up a different log file: +# +# logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log") +# I18n.missing_translations_logger = logger + +module I18n + @@missing_translations_logger = nil + + class << self + def missing_translations_logger + @@missing_translations_logger ||= begin + require 'logger' unless defined?(Logger) + Logger.new(STDOUT) + end + end + + def missing_translations_logger=(logger) + @@missing_translations_logger = logger + end + + def missing_translations_log_handler(exception, locale, key, options) + if MissingTranslationData === exception + missing_translations_logger.warn(exception.message) + return exception.message + else + raise exception + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/globalize/load_path.rb b/vendor/plugins/globalize2/lib/globalize/load_path.rb new file mode 100644 index 00000000..a49825b3 --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/load_path.rb @@ -0,0 +1,63 @@ +# Locale load_path and Locale loading support. +# +# To use this include the Globalize::LoadPath::I18n module to I18n like this: +# +# I18n.send :include, Globalize::LoadPath::I18n +# +# Clients can add load_paths using: +# +# I18n.load_path.add load_path, 'rb', 'yml' # pass any number of extensions like this +# I18n.load_path << 'path/to/dir' # usage without an extension, defaults to 'yml' +# +# And load locale data using either of: +# +# I18n.load_locales 'en-US', 'de-DE' +# I18n.load_locale 'en-US' +# +# This will lookup all files named like: +# +# 'path/to/dir/all.yml' +# 'path/to/dir/en-US.yml' +# 'path/to/dir/en-US/*.yml' +# +# The filenames will be passed to I18n.load_translations which delegates to +# the backend. So the actual behaviour depends on the implementation of the +# backend. I18n::Backend::Simple will be able to read YAML and plain Ruby +# files. See the documentation for I18n.load_translations for details. + +module Globalize + class LoadPath < Array + def extensions + @extensions ||= ['rb', 'yml'] + end + attr_writer :extensions + + def locales + @locales ||= ['*'] + end + attr_writer :locales + + def <<(path) + push path + end + + def push(*paths) + super(*paths.map{|path| filenames(path) }.flatten.uniq.sort) + end + + protected + + def filenames(path) + return [path] if File.file? path + patterns(path).map{|pattern| Dir[pattern] } + end + + def patterns(path) + locales.map do |locale| + extensions.map do |extension| + %W(#{path}/all.#{extension} #{path}/#{locale}.#{extension} #{path}/#{locale}/**/*.#{extension}) + end + end.flatten.uniq + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb b/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb new file mode 100644 index 00000000..c4acd57a --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb @@ -0,0 +1,63 @@ +require 'globalize/locale/language_tag' + +module I18n + @@fallbacks = nil + + class << self + # Returns the current fallbacks. Defaults to +Globalize::Locale::Fallbacks+. + def fallbacks + @@fallbacks ||= Globalize::Locale::Fallbacks.new + end + + # Sets the current fallbacks. Used to set a custom fallbacks instance. + def fallbacks=(fallbacks) + @@fallbacks = fallbacks + end + end +end + +module Globalize + module Locale + class Fallbacks < Hash + def initialize(*defaults) + @map = {} + map defaults.pop if defaults.last.is_a?(Hash) + + defaults = [I18n.default_locale.to_sym] if defaults.empty? + self.defaults = defaults + end + + def defaults=(defaults) + @defaults = defaults.map{|default| compute(default, false) }.flatten << :root + end + attr_reader :defaults + + def [](tag) + tag = tag.to_sym + has_key?(tag) ? fetch(tag) : store(tag, compute(tag)) + end + + def map(mappings) + mappings.each do |from, to| + from, to = from.to_sym, Array(to) + to.each do |to| + @map[from] ||= [] + @map[from] << to.to_sym + end + end + end + + protected + + def compute(tags, include_defaults = true) + result = Array(tags).collect do |tag| + tags = LanguageTag::tag(tag.to_sym).parents(true).map! {|t| t.to_sym } + tags.each{|tag| tags += compute(@map[tag]) if @map[tag] } + tags + end.flatten + result.push *defaults if include_defaults + result.uniq + end + end + end +end diff --git a/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb new file mode 100644 index 00000000..d9aae54f --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb @@ -0,0 +1,81 @@ +# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag +# +# SimpleParser does not implement advanced usages such as grandfathered tags + +module Globalize + module Locale + module Rfc4646 + SUBTAGS = [:language, :script, :region, :variant, :extension, :privateuse, :grandfathered] + FORMATS = {:language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase} + end + + class LanguageTag < Struct.new(*Rfc4646::SUBTAGS) + class << self + def parser + @@parser ||= SimpleParser + end + + def parser=(parser) + @@parser = parser + end + + def tag(tag) + matches = parser.match(tag) + new *matches if matches + end + end + + Rfc4646::FORMATS.each do |name, format| + define_method(name) { self[name].send(format) unless self[name].nil? } + end + + def to_sym + to_s.to_sym + end + + def to_s + @tag ||= to_a.compact.join("-") + end + + def to_a + members.collect {|attr| self.send(attr) } + end + + def parent + segs = to_a.compact + segs.length < 2 ? nil : LanguageTag.tag(segs[0..(segs.length-2)].join('-')) + end + + def parents(include_self = true) + result, parent = [], self.dup + result << parent if include_self + while parent = parent.parent + result << parent + end + result + end + + module SimpleParser + PATTERN = %r{\A(?: + ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language + (?:-([a-z]{4}))? # script + (?:-([a-z]{2}|\d{3}))? # region + (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant + (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension + (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag + (x(?:-[0-9a-z]{1,8})+)| # privateuse tag + /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered + )\z}xi + + class << self + def match(tag) + c = PATTERN.match(tag.to_s).captures + c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here? + rescue + false + end + end + end + end + end +end diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb new file mode 100644 index 00000000..450729c6 --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb @@ -0,0 +1,38 @@ +require 'globalize/translation' +require 'globalize/locale/fallbacks' +require 'globalize/model/active_record/adapter' +require 'globalize/model/active_record/translated' + +module Globalize + module Model + module ActiveRecord + class << self + def create_proxy_class(klass) + Object.const_set "#{klass.name}Translation", Class.new(::ActiveRecord::Base){ + belongs_to "#{klass.name.underscore}".intern + + def locale + read_attribute(:locale).to_sym + end + + def locale=(locale) + write_attribute(:locale, locale.to_s) + end + } + end + + def define_accessors(klass, attr_names) + attr_names.each do |attr_name| + klass.send :define_method, attr_name, lambda { + globalize.fetch I18n.locale, attr_name + } + klass.send :define_method, "#{attr_name}=", lambda {|val| + globalize.stash I18n.locale, attr_name, val + self[attr_name] = val + } + end + end + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb new file mode 100644 index 00000000..12d7564b --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb @@ -0,0 +1,77 @@ +module Globalize + module Model + class AttributeStash < Hash + def read(locale, attr_name) + locale = locale.to_sym + self[locale] ||= {} + self[locale][attr_name] + end + + def write(locale, attr_name, value) + locale = locale.to_sym + self[locale] ||= {} + self[locale][attr_name] = value + end + end + + class Adapter + def initialize(record) + @record = record + @cache = AttributeStash.new + @stash = AttributeStash.new + end + + def fetch(locale, attr_name) + # locale = I18n.locale + @cache.read(locale, attr_name) || begin + value = fetch_attribute locale, attr_name + @cache.write locale, attr_name, value if value && value.locale == locale + value + end + end + + def stash(locale, attr_name, value) + @stash.write locale, attr_name, value + @cache.write locale, attr_name, value + end + + def update_translations! + @stash.each do |locale, attrs| + translation = @record.globalize_translations.find_or_initialize_by_locale(locale.to_s) + attrs.each{|attr_name, value| translation[attr_name] = value } + translation.save! + end + @stash.clear + end + + # Clears the cache + def clear + @cache.clear + end + + private + + def fetch_attribute(locale, attr_name) + fallbacks = I18n.fallbacks[locale].map{|tag| tag.to_s}.map(&:to_sym) + translations = @record.globalize_translations.by_locales(fallbacks) + result, requested_locale = nil, locale + + # Walk through the fallbacks, starting with the current locale itself, and moving + # to the next best choice, until we find a match. + # Check the @globalize_set_translations cache first to see if we've just changed the + # attribute and not saved yet. + fallbacks.each do |fallback| + result = @stash.read(fallback, attr_name) || begin + translation = translations.detect {|tr| tr.locale == fallback } + translation && translation.send(attr_name) + end + if result + locale = fallback + break + end + end + result && Translation::Attribute.new(result, :locale => locale, :requested_locale => requested_locale) + end + end + end +end diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb new file mode 100644 index 00000000..710cde5d --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb @@ -0,0 +1,111 @@ +module Globalize + module Model + + class MigrationError < StandardError; end + class UntranslatedMigrationField < MigrationError; end + class MigrationMissingTranslatedField < MigrationError; end + class BadMigrationFieldType < MigrationError; end + + module ActiveRecord + module Translated + def self.included(base) + base.extend ActMethods + end + + module ActMethods + def translates(*attr_names) + options = attr_names.extract_options! + options[:translated_attributes] = attr_names + + # Only set up once per class + unless included_modules.include? InstanceMethods + class_inheritable_accessor :globalize_options + include InstanceMethods + extend ClassMethods + + proxy_class = Globalize::Model::ActiveRecord.create_proxy_class(self) + has_many :globalize_translations, :class_name => proxy_class.name, :extend => Extensions + + after_save :update_globalize_record + + def i18n_attr(attribute_name) + self.name.underscore + "_translations.#{attribute_name}" + end + end + + self.globalize_options = options + Globalize::Model::ActiveRecord.define_accessors(self, attr_names) + + # Import any callbacks that have been defined by extensions to Globalize2 + # and run them. + extend Callbacks + Callbacks.instance_methods.each {|cb| send cb } + end + end + + # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here + # and they'll be called at the end of the translates class method. + module Callbacks + end + + # Extension to the has_many :globalize_translations association + module Extensions + def by_locales(locales) + find :all, :conditions => { :locale => locales.map(&:to_s) } + end + end + + module ClassMethods + def method_missing(method, *args) + if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym) + find(:first, :joins => :globalize_translations, + :conditions => [i18n_attr($1)+" = ? AND "+i18n_attr('locale')+" IN (?)", + args.first,I18n.fallbacks[I18n.locale].map{|tag| tag.to_s}]) + else + super + end + end + + def create_translation_table!(fields) + translated_fields = self.globalize_options[:translated_attributes] + translated_fields.each do |f| + raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f] + end + fields.each do |name, type| + unless translated_fields.member? name + raise UntranslatedMigrationField, "Can't migrate untranslated field: #{name}" + end + unless [ :string, :text ].member? type + raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text" + end + end + translation_table_name = self.name.underscore + '_translations' + self.connection.create_table(translation_table_name) do |t| + t.references self.table_name.singularize + t.string :locale + fields.each do |name, type| + t.column name, type + end + t.timestamps + end + end + + def drop_translation_table! + translation_table_name = self.name.underscore + '_translations' + self.connection.drop_table translation_table_name + end + end + + module InstanceMethods + def globalize + @globalize ||= Adapter.new self + end + + def update_globalize_record + globalize.update_translations! + end + end + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/globalize/translation.rb b/vendor/plugins/globalize2/lib/globalize/translation.rb new file mode 100644 index 00000000..a80afcd7 --- /dev/null +++ b/vendor/plugins/globalize2/lib/globalize/translation.rb @@ -0,0 +1,32 @@ +module Globalize + # Translations are simple value objects that carry some context information + # alongside the actual translation string. + + class Translation < String + class Attribute < Translation + attr_accessor :requested_locale, :locale, :key + end + + class Static < Translation + attr_accessor :requested_locale, :locale, :key, :options, :plural_key, :original + + def initialize(string, meta = nil) + self.original = string + super + end + end + + def initialize(string, meta = nil) + set_meta meta + super string + end + + def fallback? + locale.to_sym != requested_locale.to_sym + end + + def set_meta(meta) + meta.each {|name, value| send :"#{name}=", value } if meta + end + end +end \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/locale/root.yml b/vendor/plugins/globalize2/lib/locale/root.yml new file mode 100644 index 00000000..2ec2b3bf --- /dev/null +++ b/vendor/plugins/globalize2/lib/locale/root.yml @@ -0,0 +1,3 @@ +root: + bidi: + direction: left-to-right \ No newline at end of file diff --git a/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb b/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb new file mode 100644 index 00000000..e6f90d81 --- /dev/null +++ b/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb @@ -0,0 +1,40 @@ +module I18n + @@load_path = nil + @@default_locale = :'en-US' + + class << self + def load_path + @@load_path ||= [] + end + + def load_path=(load_path) + @@load_path = load_path + end + end +end + +I18n::Backend::Simple.module_eval do + def initialized? + @initialized ||= false + end + + protected + + def init_translations + load_translations(*I18n.load_path) + @initialized = true + end + + def lookup(locale, key, scope = []) + return unless key + init_translations unless initialized? + keys = I18n.send :normalize_translation_keys, locale, key, scope + keys.inject(translations){|result, k| result[k.to_sym] or return nil } + end +end + +rails_dir = File.expand_path "#{File.dirname(__FILE__)}/../../../rails/" +paths = %w(actionpack/lib/action_view/locale/en-US.yml + activerecord/lib/active_record/locale/en-US.yml + activesupport/lib/active_support/locale/en-US.yml) +paths.each{|path| I18n.load_path << "#{rails_dir}/#{path}" } -- cgit v1.3