mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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.
This commit is contained in:
parent
99a0254eff
commit
98a76a50ed
2 changed files with 70 additions and 23 deletions
|
@ -88,24 +88,15 @@ module ActionView
|
|||
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 @@ module ActionView
|
|||
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 @@ module ActionView
|
|||
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 @@ class TranslationHelperTest < ActiveSupport::TestCase
|
|||
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 @@ class TranslationHelperTest < ActiveSupport::TestCase
|
|||
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 @@ class TranslationHelperTest < ActiveSupport::TestCase
|
|||
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 @@ class TranslationHelperTest < ActiveSupport::TestCase
|
|||
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"
|
||||
|
|
Loading…
Reference in a new issue