提交 98a76a50 编写于 作者: J Jonathan Hefner

Refactor Action View `translate` helper

This refactor incidentally fixes a corner case when `translate` is
called with a block, the translation is missing, and
`debug_missing_translation` is false.

This commit adds a test for the above corner case, and additional tests
for existing behavior.
上级 99a0254e
......@@ -88,24 +88,15 @@ def translate(key, **options)
fully_resolved_key = scope_key_by_partial(key)
if html_safe_translation_key?(key)
html_safe_options = options.dup
options.except(*I18n::RESERVED_KEYS).each do |name, value|
unless name == :count && value.is_a?(Numeric)
html_safe_options[name] = ERB::Util.html_escape(value.to_s)
end
end
html_safe_options = html_escape_translation_options(options)
html_safe_options[:default] = MISSING_TRANSLATION unless html_safe_options[:default].blank?
translation = I18n.translate(fully_resolved_key, **html_safe_options.merge(raise: i18n_raise))
if translation.equal?(MISSING_TRANSLATION)
translated_text = options[:default].first
elsif translation.respond_to?(:map)
translated_text = translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
else
translated_text = translation.respond_to?(:html_safe) ? translation.html_safe : translation
translated_text = html_safe_translation(translation)
end
else
translated_text = I18n.translate(fully_resolved_key, **options.merge(raise: i18n_raise))
......@@ -122,18 +113,7 @@ def translate(key, **options)
else
raise e if raise_error
keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
title = +"translation missing: #{keys.join('.')}"
interpolations = options.except(:default, :scope)
if interpolations.any?
title << ", " << interpolations.map { |k, v| "#{k}: #{ERB::Util.html_escape(v)}" }.join(", ")
end
return title unless ActionView::Base.debug_missing_translation
translated_fallback = content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
translated_fallback = missing_translation(e, options)
if block_given?
yield(translated_fallback, scope_key_by_partial(key))
......@@ -172,9 +152,46 @@ def scope_key_by_partial(key)
end
end
def html_escape_translation_options(options)
html_safe_options = options.dup
options.except(*I18n::RESERVED_KEYS).each do |name, value|
unless name == :count && value.is_a?(Numeric)
html_safe_options[name] = ERB::Util.html_escape(value.to_s)
end
end
html_safe_options
end
def html_safe_translation_key?(key)
/(?:_|\b)html\z/.match?(key.to_s)
end
def html_safe_translation(translation)
if translation.respond_to?(:map)
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
else
translation.respond_to?(:html_safe) ? translation.html_safe : translation
end
end
def missing_translation(error, options)
keys = I18n.normalize_keys(error.locale, error.key, error.options[:scope])
title = +"translation missing: #{keys.join(".")}"
interpolations = options.except(:default, :scope)
if interpolations.any?
title << ", " << interpolations.map { |k, v| "#{k}: #{ERB::Util.html_escape(v)}" }.join(", ")
end
if ActionView::Base.debug_missing_translation
content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
else
title
end
end
end
end
end
......@@ -102,6 +102,15 @@ def test_raises_missing_translation_message_with_raise_config_option
ActionView::Base.raise_on_missing_translations = false
end
def test_raise_arg_overrides_raise_config_option
ActionView::Base.raise_on_missing_translations = true
expected = "translation missing: en.translations.missing"
assert_equal expected, translate(:"translations.missing", raise: false)
ensure
ActionView::Base.raise_on_missing_translations = false
end
def test_raises_missing_translation_message_with_raise_option
assert_raise(I18n::MissingTranslationData) do
translate(:"translations.missing", raise: true)
......@@ -164,6 +173,16 @@ def test_missing_translation_scoped_by_partial_yield_block
assert_equal expected, view.render(template: "translations/templates/missing_yield_block").strip
end
def test_missing_translation_scoped_by_partial_yield_block_without_debug_wrapper
old_debug_missing_translation = ActionView::Base.debug_missing_translation
ActionView::Base.debug_missing_translation = false
expected = "translations.templates.missing_yield_block.missing: translation missing: en.translations.templates.missing_yield_block.missing"
assert_equal expected, view.render(template: "translations/templates/missing_yield_block").strip
ensure
ActionView::Base.debug_missing_translation = old_debug_missing_translation
end
def test_missing_translation_with_default_scoped_by_partial_yield_block
expected = "translations.templates.missing_with_default_yield_block.missing: Default"
assert_equal expected, view.render(template: "translations/templates/missing_with_default_yield_block").strip
......@@ -229,6 +248,12 @@ def test_translate_with_missing_default_and_raise_option
end
end
def test_translate_with_html_key_and_missing_default_and_raise_option
assert_raise(I18n::MissingTranslationData) do
translate(:"translations.missing_html", default: :"translations.missing_html", raise: true)
end
end
def test_translate_with_two_defaults_named_html
translation = translate(:'translations.missing', default: [:'translations.missing_html', :'translations.hello_html'])
assert_equal "<a>Hello World</a>", translation
......@@ -289,6 +314,11 @@ def test_translate_with_nil_default
assert_nil translation
end
def test_translate_bulk_lookup
translations = translate([:"translations.foo", :"translations.foo"])
assert_equal ["Foo", "Foo"], translations
end
def test_translate_does_not_change_options
options = {}
if RUBY_VERSION >= "2.7"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册