summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2012-11-18 17:41:31 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2012-11-18 17:41:31 +0000
commit3739810afa3545e6747a9111185dc8808fff6078 (patch)
treeacc4a1312a72a2f3f071161091170508c6443cbd
parentf36b3fff60473dec197f17f632213785a6982382 (diff)
downloadredmine-3739810afa3545e6747a9111185dc8808fff6078.tar.gz
redmine-3739810afa3545e6747a9111185dc8808fff6078.zip
Adds a custom i18n backend that lazily loads translations files.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@10843 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--config/initializers/30-redmine.rb3
-rw-r--r--lib/redmine/i18n.rb71
2 files changed, 71 insertions, 3 deletions
diff --git a/config/initializers/30-redmine.rb b/config/initializers/30-redmine.rb
index 11a248959..1018ca18c 100644
--- a/config/initializers/30-redmine.rb
+++ b/config/initializers/30-redmine.rb
@@ -1,6 +1,5 @@
I18n.default_locale = 'en'
-# Adds fallback to default locale for untranslated strings
-I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
+I18n.backend = Redmine::I18n::Backend.new
require 'redmine'
diff --git a/lib/redmine/i18n.rb b/lib/redmine/i18n.rb
index 12445b450..304175ee5 100644
--- a/lib/redmine/i18n.rb
+++ b/lib/redmine/i18n.rb
@@ -67,7 +67,7 @@ module Redmine
end
def valid_languages
- @@valid_languages ||= Dir.glob(File.join(Rails.root, 'config', 'locales', '*.yml')).collect {|f| File.basename(f).split('.').first}.collect(&:to_sym)
+ ::I18n.available_locales
end
def find_language(lang)
@@ -84,5 +84,74 @@ module Redmine
def current_language
::I18n.locale
end
+
+ # Custom backend based on I18n::Backend::Simple with the following changes:
+ # * lazy loading of translation files
+ # * available_locales are determined by looking at translation file names
+ class Backend
+ (class << self; self; end).class_eval { public :include }
+
+ module Implementation
+ include ::I18n::Backend::Base
+
+ # Stores translations for the given locale in memory.
+ # This uses a deep merge for the translations hash, so existing
+ # translations will be overwritten by new ones only at the deepest
+ # level of the hash.
+ def store_translations(locale, data, options = {})
+ locale = locale.to_sym
+ translations[locale] ||= {}
+ data = data.deep_symbolize_keys
+ translations[locale].deep_merge!(data)
+ end
+
+ # Get available locales from the translations filenames
+ def available_locales
+ @available_locales ||= ::I18n.load_path.map {|path| File.basename(path, '.*').to_sym}.uniq.sort
+ end
+
+ # Clean up translations
+ def reload!
+ @translations = nil
+ @available_locales = nil
+ super
+ end
+
+ protected
+
+ def init_translations(locale)
+ locale = locale.to_s
+ paths = ::I18n.load_path.select {|path| File.basename(path, '.*') == locale}
+ load_translations(paths)
+ translations[locale] ||= {}
+ end
+
+ def translations
+ @translations ||= {}
+ end
+
+ # Looks up a translation from the translations hash. Returns nil if
+ # eiher key is nil, or locale, scope or key do not exist as a key in the
+ # nested translations hash. Splits keys or scopes containing dots
+ # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
+ # <tt>%w(currency format)</tt>.
+ def lookup(locale, key, scope = [], options = {})
+ init_translations(locale) unless translations.key?(locale)
+ keys = ::I18n.normalize_keys(locale, key, scope, options[:separator])
+
+ keys.inject(translations) do |result, _key|
+ _key = _key.to_sym
+ return nil unless result.is_a?(Hash) && result.has_key?(_key)
+ result = result[_key]
+ result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
+ result
+ end
+ end
+ end
+
+ include Implementation
+ # Adds fallback to default locale for untranslated strings
+ include ::I18n::Backend::Fallbacks
+ end
end
end