Treat html suffix in controller translation

There are some difference between translation in a view and translation
in a controller.
This will treat html suffix in controller translation.

Closes #27862.

Co-authored-by: Rui Onodera <deraru@gmail.com>
Co-authored-by: Gavin Miller <gavingmiller@gmail.com>
This commit is contained in:
Rafael Mendonça França 2021-10-08 21:21:53 +00:00 committed by GitHub
parent 5e1a039a1d
commit a5247bb908
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 1 deletions

View File

@ -1,3 +1,7 @@
* Treat html suffix in controller translation.
*Rui Onodera*, *Gavin Miller*
* Allow permitting numeric params.
Previously it was impossible to permit different fields on numeric parameters.

View File

@ -22,7 +22,20 @@ module AbstractController
end
i18n_raise = options.fetch(:raise, self.raise_on_missing_translations)
I18n.translate(key, **options, raise: i18n_raise)
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
translation = I18n.translate(key, **html_safe_options, raise: i18n_raise)
translation.respond_to?(:html_safe) ? translation.html_safe : translation
else
I18n.translate(key, **options, raise: i18n_raise)
end
end
alias :t :translate
@ -31,5 +44,10 @@ module AbstractController
I18n.localize(object, **options)
end
alias :l :localize
private
def html_safe_translation_key?(key)
/(\b|_|\.)html$/.match?(key.to_s)
end
end
end

View File

@ -20,6 +20,10 @@ module AbstractController
translation: {
index: {
foo: "bar",
hello: "<a>Hello World</a>",
hello_html: "<a>Hello World</a>",
interpolated_html: "<a>Hello %{word}</a>",
nested: { html: "<a>nested</a>" }
},
no_action: "no_action_tr",
},
@ -95,6 +99,43 @@ module AbstractController
assert_equal expected, @controller.l(time)
end
end
def test_translate_does_not_mark_plain_text_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t(".hello")
assert_equal "<a>Hello World</a>", translation
assert_equal false, translation.html_safe?
end
end
def test_translate_marks_translations_with_a_html_suffix_as_safe_html
@controller.stub :action_name, :index do
translation = @controller.t(".hello_html")
assert_equal "<a>Hello World</a>", translation
assert_equal true, translation.html_safe?
end
end
def test_translate_marks_translation_with_nested_html_key
@controller.stub :action_name, :index do
translation = @controller.t(".nested.html")
assert_equal "<a>nested</a>", translation
assert_equal true, translation.html_safe?
end
end
def test_translate_escapes_interpolations_in_translations_with_a_html_suffix
word_struct = Struct.new(:to_s)
@controller.stub :action_name, :index do
translation = @controller.t(".interpolated_html", word: "<World>")
assert_equal "<a>Hello &lt;World&gt;</a>", translation
assert_equal true, translation.html_safe?
translation = @controller.t(".interpolated_html", word: word_struct.new("<World>"))
assert_equal "<a>Hello &lt;World&gt;</a>", translation
assert_equal true, translation.html_safe?
end
end
end
end
end