Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Allow symbol links to be resolved recursively. Imagine the following …

…setup:

  en:
    activemodel:
      errors:
        messages:
          blank: "can't be blank"

  en:
    activerecord:
      errors:
        messages: :"activemodel.errors.messages"

Prior to this patch, the following did not work:

  I18n.t "activerecord.errors.messages.blank"

Now it does. This patch also resolves links for Fast backend when
storing the translations, so such links are also optimized. Finally,
it also unifies ActiveRecord and Fast backend implementation.
  • Loading branch information...
commit 2c50bd209f3fc24fe9dfa694c81be64340f09b7d 1 parent 2e13fc1
@josevalim josevalim authored committed
View
9 lib/i18n/backend/base.rb
@@ -114,11 +114,10 @@ def lookup(locale, key, scope = [], separator = nil)
keys = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
keys.inject(translations) do |result, key|
key = key.to_sym
- if result.respond_to?(:has_key?) and result.has_key?(key)
- result[key]
- else
- return nil
- end
+ return nil unless result.is_a?(Hash) && result.has_key?(key)
+ result = result[key]
+ result = resolve(locale, key, result, :scope => scope, :separator => separator) if result.is_a?(Symbol)
+ result
end
end
View
18 lib/i18n/backend/fast.rb
@@ -35,22 +35,8 @@ def init_translations
protected
# flatten_hash({:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}})
# # => {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"}
- def flatten_hash(h, nested_stack = [], flattened_h = {})
- h.each_pair do |k, v|
- new_nested_stack = nested_stack + [escape_default_separator(k)]
- flattened_h[nested_stack_to_flat_key(new_nested_stack)] = v
- flatten_hash(v, new_nested_stack, flattened_h) if v.kind_of?(Hash)
- end
-
- flattened_h
- end
-
- def escape_default_separator(key)
- key.to_s.tr(I18n.default_separator, SEPARATOR_ESCAPE_CHAR)
- end
-
- def nested_stack_to_flat_key(nested_stack)
- nested_stack.join(I18n.default_separator).to_sym
+ def flatten_hash(h, nested_stack = [], flattened_h = {}, orig_h=h)
+ deep_symbolize_keys(wind_keys(h, nil, true))
end
def flatten_translations(translations)
View
37 lib/i18n/backend/helpers.rb
@@ -1,6 +1,8 @@
module I18n
module Backend
module Helpers
+ SEPARATOR_ESCAPE_CHAR = "\001"
+
# Return a new hash with all keys and nested keys converted to symbols.
def deep_symbolize_keys(hash)
hash.inject({}) { |result, (key, value)|
@@ -13,16 +15,41 @@ def deep_symbolize_keys(hash)
# Flatten keys for nested Hashes by chaining up keys using the separator
# >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
# => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
- def wind_keys(hash, separator = ".", prev_key = nil, result = {})
- hash.inject(result) do |result, pair|
- key, value = *pair
+ def wind_keys(hash, separator = nil, subtree = false, prev_key = nil, result = {}, orig_hash=hash)
+ separator ||= I18n.default_separator
+
+ hash.each_pair do |key, value|
+ key = escape_default_separator(key, separator)
curr_key = [prev_key, key].compact.join(separator)
+
+ if value.is_a?(Symbol)
+ value = hash_lookup(orig_hash, value, separator) ||
+ hash_lookup(hash, value, separator)
+ end
+
if value.is_a?(Hash)
- wind_keys(value, separator, curr_key, result)
+ result[curr_key] = value if subtree
+ wind_keys(value, separator, subtree, curr_key, result, orig_hash)
else
result[curr_key] = value
end
- result
+ end
+
+ result
+ end
+
+ def escape_default_separator(key, separator=nil)
+ key.to_s.tr(separator || I18n.default_separator, SEPARATOR_ESCAPE_CHAR)
+ end
+
+ def hash_lookup(hash, keys, separator = ".")
+ keys.to_s.split(separator).inject(hash) do |result, key|
+ key = key.to_sym
+ if result.respond_to?(:has_key?) and result.has_key?(key)
+ result[key]
+ else
+ return nil
+ end
end
end
View
5 test/api/link.rb
@@ -22,6 +22,11 @@ module Link
setup_linked_translations
assert_equal('baz', I18n.backend.translate('en', :link_to_baz, :scope => :bar))
end
+
+ define_method "test linked lookup: given the first key resolves to a symbol it looks up the symbol with remaining keys" do
+ setup_linked_translations
+ assert_equal('baz', I18n.backend.translate('en', :"link_to_bar.baz"))
+ end
protected
View
9 test/test_helper.rb
@@ -1,12 +1,13 @@
# encoding: utf-8
-$: << "lib"
-$: << File.expand_path(File.dirname(__FILE__))
+$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
+$:.unshift File.expand_path(File.dirname(__FILE__))
-require 'rubygems'
-require 'test/unit'
require 'i18n'
require 'i18n/core_ext/object/meta_class'
+
+require 'rubygems'
+require 'test/unit'
require 'time'
require 'yaml'

0 comments on commit 2c50bd2

Please sign in to comment.
Something went wrong with that request. Please try again.