diff --git a/lib/i18n.rb b/lib/i18n.rb index 13f1bfd1..24d68d64 100644 --- a/lib/i18n.rb +++ b/lib/i18n.rb @@ -23,6 +23,7 @@ module I18n exception_handler fallback fallback_in_progress + fallback_original_locale format object raise diff --git a/lib/i18n/backend/fallbacks.rb b/lib/i18n/backend/fallbacks.rb index 1acdbd68..acab6dfe 100644 --- a/lib/i18n/backend/fallbacks.rb +++ b/lib/i18n/backend/fallbacks.rb @@ -43,7 +43,7 @@ def translate(locale, key, options = EMPTY_HASH) return super if options[:fallback_in_progress] default = extract_non_symbol_default!(options) if options[:default] - fallback_options = options.merge(:fallback_in_progress => true) + fallback_options = options.merge(:fallback_in_progress => true, fallback_original_locale: locale) I18n.fallbacks[locale].each do |fallback| begin catch(:exception) do @@ -64,6 +64,17 @@ def translate(locale, key, options = EMPTY_HASH) throw(:exception, I18n::MissingTranslation.new(locale, key, options)) end + def resolve(locale, object, subject, options = EMPTY_HASH) + return subject if options[:resolve] == false + return super unless subject.is_a?(Symbol) + + result = catch(:exception) do + options.delete(:fallback_in_progress) + I18n.translate(subject, **options.merge(locale: options[:fallback_original_locale], throw: true)) + end + result unless result.is_a?(MissingTranslation) + end + def extract_non_symbol_default!(options) defaults = [options[:default]].flatten first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)} diff --git a/lib/i18n/tests/localization/procs.rb b/lib/i18n/tests/localization/procs.rb index 5f3e9bf5..7db45d1d 100644 --- a/lib/i18n/tests/localization/procs.rb +++ b/lib/i18n/tests/localization/procs.rb @@ -74,6 +74,7 @@ def self.inspect_args(args, kwargs) arg.strftime('%a, %d %b %Y') when Hash arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) arg.inspect else arg.inspect diff --git a/lib/i18n/tests/procs.rb b/lib/i18n/tests/procs.rb index dad76de9..6abd8612 100644 --- a/lib/i18n/tests/procs.rb +++ b/lib/i18n/tests/procs.rb @@ -53,7 +53,13 @@ module Procs def self.filter_args(*args) - args.map {|arg| arg.delete(:fallback_in_progress) if arg.is_a?(Hash) ; arg }.inspect + args.map do |arg| + if arg.is_a?(Hash) + arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) + end + arg + end.inspect end end end diff --git a/test/backend/fallbacks_test.rb b/test/backend/fallbacks_test.rb index d2c9ad36..c9e23f1d 100644 --- a/test/backend/fallbacks_test.rb +++ b/test/backend/fallbacks_test.rb @@ -191,6 +191,54 @@ def setup end end +# See Issue #590 +class I18nBackendFallbacksSymbolReolveRestartsLookupAtOriginalLocale < I18n::TestCase + class Backend < I18n::Backend::Simple + include I18n::Backend::Fallbacks + end + + def setup + super + I18n.backend = Backend.new + I18n.enforce_available_locales = false + I18n.fallbacks = [:root] + store_translations(:ak, + 'calendars' => { + 'gregorian' => { + 'months' => { + 'format' => { + 'abbreviated' => { + 1 => 'S-Ɔ' + # Other months omitted for brevity + } + } + } + } + }) + store_translations(:root, + 'calendars' => { + 'gregorian' => { + 'months' => { + 'format' => { + 'abbreviated' => :"calendars.gregorian.months.format.wide", + 'wide' => { + 1 => 'M01' + # Other months omitted for brevity + } + }, + 'stand-alone' => { + 'abbreviated' => :"calendars.gregorian.months.format.abbreviated" + } + } + } + }) + end + + test 'falls back to original locale when symbol resolved at fallback locale' do + assert_equal({ 1 => 'S-Ɔ' }, I18n.t('calendars.gregorian.months.stand-alone.abbreviated', locale: :"ak-GH")) + end +end + class I18nBackendFallbacksLocalizeTest < I18n::TestCase class Backend < I18n::Backend::Simple