Skip to content

Commit

Permalink
Make i18n fallbacks configurable and fallback to the default locale b…
Browse files Browse the repository at this point in the history
…y default in production [#4428 state:resolved]

Allows to configure locale fallbacks through config.i18n.fallbacks. The default setting
config.i18n.fallbacks = true in production.rb will make I18n.t lookup fallback to the
I18n.default_locale if a translation could not be found for the current or given locale.

config.fallbacks = true

config.fallbacks.map = { :ca => :es }
config.fallbacks.defaults = [:'es-ES', :es]

config.fallbacks = [:'es-ES', :es]

config.fallbacks = { :ca => :es }

config.fallbacks = [:'es-ES', :es, { :ca => :es }]

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
  • Loading branch information
Sven Fuchs authored and lifo committed Apr 17, 2010
1 parent b7693dc commit 9a3a4d6
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
35 changes: 35 additions & 0 deletions activesupport/lib/active_support/railtie.rb
Expand Up @@ -33,6 +33,7 @@ class Railtie < Rails::Railtie
config.i18n = ActiveSupport::OrderedOptions.new
config.i18n.railties_load_path = []
config.i18n.load_path = []
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new

initializer "i18n.initialize" do
ActiveSupport.on_load(:i18n) do
Expand All @@ -53,12 +54,46 @@ class Railtie < Rails::Railtie
app.config.i18n.load_path.unshift(*value)
when :load_path
I18n.load_path += value
when :fallbacks
init_fallbacks(value) if value && validate_fallbacks(value)
else
I18n.send("#{setting}=", value)
end
end

I18n.reload!
end

class << self
protected

def init_fallbacks(fallbacks)
include_fallbacks_module
args = case fallbacks
when ActiveSupport::OrderedOptions
[*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
when Hash, Array
Array.wrap(fallbacks)
else # TrueClass
[]
end
I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
end

def include_fallbacks_module
I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
end

def validate_fallbacks(fallbacks)
case fallbacks
when ActiveSupport::OrderedOptions
!fallbacks.empty?
when TrueClass, Array, Hash
true
else
raise "Unexpected fallback type #{fallbacks.inspect}"
end
end
end
end
end
Expand Up @@ -39,4 +39,8 @@

# Enable threaded mode
# config.threadsafe!

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true
end
86 changes: 86 additions & 0 deletions railties/test/railties/i18n_railtie_test.rb
@@ -0,0 +1,86 @@
require "isolation/abstract_unit"

module RailtiesTest
class I18nRailtieTest < Test::Unit::TestCase
include ActiveSupport::Testing::Isolation

def setup
build_app
boot_rails
FileUtils.rm_rf("#{app_path}/config/environments")
require "rails/all"
@old_path = I18n.load_path
end

def teardown
I18n.load_path = @old_path || []
I18n.backend = nil
end

def load_app
require "#{app_path}/config/environment"
end

def assert_fallbacks(fallbacks)
fallbacks.each do |locale, expected|
actual = I18n.fallbacks[locale]
assert_equal expected, actual, "expected fallbacks for #{locale.inspect} to be #{expected.inspect}, but were #{actual.inspect}"
end
end

def assert_no_fallbacks
assert !I18n.backend.class.included_modules.include?(I18n::Backend::Fallbacks)
end

test "config.i18n.load_path gets added to I18n.load_path" do
I18n.load_path = ['existing/path/to/locales']
I18n::Railtie.config.i18n.load_path = ['new/path/to/locales']
load_app

assert I18n.load_path.include?('existing/path/to/locales')
assert I18n.load_path.include?('new/path/to/locales')
end

test "not using config.i18n.fallbacks does not initialize I18n.fallbacks" do
I18n.backend = Class.new { include I18n::Backend::Base }.new # can't uninclude modules, so use a tmp backend class
load_app
assert_no_fallbacks
end

test "config.i18n.fallbacks = true initializes I18n.fallbacks with default settings" do
I18n::Railtie.config.i18n.fallbacks = true
load_app
assert_fallbacks :de => [:de, :en]
end

test "config.i18n.fallbacks.defaults = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
I18n::Railtie.config.i18n.fallbacks.defaults = [:'en-US']
load_app
assert_fallbacks :de => [:de, :'en-US', :en]
end

test "config.i18n.fallbacks.map = { :ca => :'es-ES' } initializes fallbacks with a mapping ca => es-ES" do
I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
load_app
assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
end

test "[shortcut] config.i18n.fallbacks = [:'en-US'] initializes fallbacks with en-US as a fallback default" do
I18n::Railtie.config.i18n.fallbacks = [:'en-US']
load_app
assert_fallbacks :de => [:de, :'en-US', :en]
end

test "[shortcut] config.i18n.fallbacks = [{ :ca => :'es-ES' }] initializes fallbacks with a mapping de-AT => de-DE" do
I18n::Railtie.config.i18n.fallbacks.map = { :ca => :'es-ES' }
load_app
assert_fallbacks :ca => [:ca, :"es-ES", :es, :en]
end

test "[shortcut] config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }] initializes fallbacks with the given arguments" do
I18n::Railtie.config.i18n.fallbacks = [:'en-US', { :ca => :'es-ES' }]
load_app
assert_fallbacks :ca => [:ca, :"es-ES", :es, :'en-US', :en]
end
end
end

0 comments on commit 9a3a4d6

Please sign in to comment.