Skip to content

Commit

Permalink
allow to configure the default scope separator, allow to pass a custo…
Browse files Browse the repository at this point in the history
…m scope separator (e.g. I18n.t(:'foo|bar', :separator => '|')
  • Loading branch information
Sven Fuchs committed May 3, 2009
1 parent e277711 commit 5b75bfb
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 22 deletions.
17 changes: 14 additions & 3 deletions lib/i18n.rb
Expand Up @@ -12,6 +12,7 @@ module I18n
@@backend = nil
@@load_path = nil
@@default_locale = :'en'
@@default_separator = '.'
@@exception_handler = :default_exception_handler

class << self
Expand Down Expand Up @@ -50,6 +51,16 @@ def available_locales
backend.available_locales
end

# Returns the current default scope separator. Defaults to '.'
def default_separator
@@default_separator
end

# Sets the current default scope separator.
def default_separator=(separator)
@@default_separator = separator
end

# Sets the exception handler.
def exception_handler=(exception_handler)
@@exception_handler = exception_handler
Expand Down Expand Up @@ -190,9 +201,9 @@ def default_exception_handler(exception, locale, key, options)
# Merges the given locale, key and scope into a single array of keys.
# Splits keys that contain dots into multiple keys. Makes sure all
# keys are Symbols.
def normalize_translation_keys(locale, key, scope)
keys = [locale] + Array(scope) + [key]
keys = keys.map { |k| k.to_s.split(/\./) }
def normalize_translation_keys(locale, key, scope, separator = nil)
keys = [locale] + Array(scope) + Array(key)
keys = keys.map { |k| k.to_s.split(separator || I18n.default_separator) }
keys.flatten.map { |k| k.to_sym }
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/i18n/backend/simple.rb
Expand Up @@ -3,7 +3,7 @@
module I18n
module Backend
class Simple
RESERVED_KEYS = [:scope, :default]
RESERVED_KEYS = [:scope, :default, :separator]
MATCH = /(\\\\)?\{\{([^\}]+)\}\}/

# Accepts a list of paths to translation files. Loads translations from
Expand All @@ -25,10 +25,10 @@ def translate(locale, key, options = {})
raise InvalidLocale.new(locale) if locale.nil?
return key.map { |k| translate(locale, k, options) } if key.is_a?(Array)

count, scope, default = options.values_at(:count, *RESERVED_KEYS)
count, scope, default, separator = options.values_at(:count, *RESERVED_KEYS)
values = options.reject { |name, value| RESERVED_KEYS.include?(name) }

entry = lookup(locale, key, scope)
entry = lookup(locale, key, scope, separator)
entry = entry.nil? ? default(locale, key, default, options) : resolve(locale, key, entry, options)

raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
Expand Down Expand Up @@ -92,10 +92,10 @@ def translations
# 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 = [])
def lookup(locale, key, scope = [], separator = nil)
return unless key
init_translations unless initialized?
keys = I18n.send(:normalize_translation_keys, locale, key, scope)
keys = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
keys.inject(translations) do |result, k|
if (x = result[k.to_sym]).nil?
return nil
Expand Down
12 changes: 10 additions & 2 deletions test/backend/simple/lookup_test.rb
Expand Up @@ -6,10 +6,18 @@ class I18nSimpleBackendLookupTest < Test::Unit::TestCase

# useful because this way we can use the backend with no key for interpolation/pluralization
def test_lookup_given_nil_as_a_key_returns_nil
assert_nil @backend.send(:lookup, 'en', nil)
assert_nil @backend.send(:lookup, :en, nil)
end

def test_lookup_given_nested_keys_looks_up_a_nested_hash_value
assert_equal 'bar', @backend.send(:lookup, 'en', :bar, [:foo])
assert_equal 'bar', @backend.send(:lookup, :en, :bar, [:foo])
end

def test_lookup_using_a_custom_separator
assert_equal 'bar', @backend.send(:lookup, :en, 'foo|bar', [], '|')
end

def test_default_using_a_custom_separator
assert_equal 'bar', @backend.send(:default, :en, :'does_not_exist', :'foo|bar', :separator => '|')
end
end
10 changes: 3 additions & 7 deletions test/backend/simple/pluralize_test.rb
Expand Up @@ -33,12 +33,8 @@ def test_interpolate_given_incomplete_pluralization_data_raises_invalid_pluraliz
assert_raises(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, {:one => 'bar'}, 2) }
end

# def test_interpolate_given_a_string_raises_invalid_pluralization_data
# assert_raises(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, 'bar', 2) }
# end
#
# def test_interpolate_given_an_array_raises_invalid_pluralization_data
# assert_raises(I18n::InvalidPluralizationData){ @backend.send(:pluralize, nil, ['bar'], 2) }
# end
def test_pluralize_given_pluralization_data_as_default
assert_equal 'bars', I18n.t(:bar, :count => 2, :default => { :one => 'bar', :other => 'bars' })
end
end

2 changes: 1 addition & 1 deletion test/backend/simple/translate_test.rb
Expand Up @@ -5,7 +5,7 @@ class I18nSimpleBackendTranslateTest < Test::Unit::TestCase
include I18nSimpleBackendTestSetup

def test_translate_calls_lookup_with_locale_given
@backend.expects(:lookup).with('de', :bar, [:foo]).returns 'bar'
@backend.expects(:lookup).with('de', :bar, [:foo], nil).returns 'bar'
@backend.translate 'de', :bar, :scope => [:foo]
end

Expand Down
29 changes: 25 additions & 4 deletions test/i18n_test.rb
Expand Up @@ -23,7 +23,7 @@ def test_uses_simple_backend_set_by_default
end

def test_can_set_backend
assert_nothing_raised{ I18n.backend = self }
assert_nothing_raised { I18n.backend = self }
assert_equal self, I18n.backend
I18n.backend = I18n::Backend::Simple.new
end
Expand All @@ -33,7 +33,7 @@ def test_uses_en_us_as_default_locale_by_default
end

def test_can_set_default_locale
assert_nothing_raised{ I18n.default_locale = 'de' }
assert_nothing_raised { I18n.default_locale = 'de' }
assert_equal 'de', I18n.default_locale
I18n.default_locale = 'en'
end
Expand All @@ -43,14 +43,35 @@ def test_uses_default_locale_as_locale_by_default
end

def test_can_set_locale_to_thread_current
assert_nothing_raised{ I18n.locale = 'de' }
assert_nothing_raised { I18n.locale = 'de' }
assert_equal 'de', I18n.locale
assert_equal 'de', Thread.current[:locale]
I18n.locale = 'en'
end

def test_defaults_to_dot_as_separator
assert_equal '.', I18n.default_separator
end

def test_can_set_default_separator
assert_nothing_raised { I18n.default_separator = "\001" }
I18n.default_separator = '.' # revert it
end

def test_normalize_keys
assert_equal [:en, :foo, :bar], I18n.send(:normalize_translation_keys, :en, :bar, :foo)
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, :'baz.buz', :'foo.bar')
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, 'baz.buz', 'foo.bar')
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, %w(baz buz), %w(foo bar))
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, [:baz, :buz], [:foo, :bar])
end

def test_uses_passed_separator_to_normalize_keys
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, :'baz|buz', :'foo|bar', '|')
end

def test_can_set_exception_handler
assert_nothing_raised{ I18n.exception_handler = :custom_exception_handler }
assert_nothing_raised { I18n.exception_handler = :custom_exception_handler }
I18n.exception_handler = :default_exception_handler # revert it
end

Expand Down

0 comments on commit 5b75bfb

Please sign in to comment.