未验证 提交 93e72cf5 编写于 作者: R Rafael Mendonça França

Merge pull request #39363 from seanpdoyle/translate-helper-yield-block

Extend `ActionView::Helpers#translate` to yield
* `ActionView::Helpers::TranslationHelper#translate` accepts a block, yielding
the translated text and the fully resolved translation key:
<%= translate(".relative_key") do |translation, resolved_key| %>
<span title="<%= resolved_key %>"><%= translation %></span>
<% end %>
*Sean Doyle*
* Ensure cache fragment digests include all relevant template dependencies when
fragments are contained in a block passed to the render helper. Remove the
virtual_path keyword arguments found in CacheHelper as they no longer possess
......
......@@ -57,6 +57,17 @@ module TranslationHelper
# that include HTML tags so that you know what kind of output to expect
# when you call translate in a template and translators know which keys
# they can provide HTML values for.
#
# To access the translated text along with the fully resolved
# translation key, <tt>translate</tt> accepts a block:
#
# <%= translate(".relative_key") do |translation, resolved_key| %>
# <span title="<%= resolved_key %>"><%= translation %></span>
# <% end %>
#
# This enables annotate translated text to be aware of the scope it was
# resolved against.
#
def translate(key, **options)
unless options[:default].nil?
remaining_defaults = Array.wrap(options.delete(:default)).compact
......@@ -74,21 +85,32 @@ def translate(key, **options)
i18n_raise = true
end
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
translation = I18n.translate(scope_key_by_partial(key), **html_safe_options.merge(raise: i18n_raise))
translation = I18n.translate(fully_resolved_key, **html_safe_options.merge(raise: i18n_raise))
if translation.respond_to?(:map)
translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
translated_text = translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
else
translation.respond_to?(:html_safe) ? translation.html_safe : translation
translated_text = translation.respond_to?(:html_safe) ? translation.html_safe : translation
end
else
I18n.translate(scope_key_by_partial(key), **options.merge(raise: i18n_raise))
translated_text = I18n.translate(fully_resolved_key, **options.merge(raise: i18n_raise))
end
if block_given?
yield(translated_text, fully_resolved_key)
else
translated_text
end
rescue I18n::MissingTranslationData => e
if remaining_defaults.present?
......@@ -100,13 +122,20 @@ def translate(key, **options)
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
content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
translated_fallback = content_tag("span", keys.last.to_s.titleize, class: "translation_missing", title: title)
if block_given?
yield(translated_fallback, scope_key_by_partial(key))
else
translated_fallback
end
end
end
alias :t :translate
......
<%= t('.foo') do |translation, key| %>
<%= key %>: <%= translation %>
<% end %>
<%= t('.foo') do |translation| %>
<%= translation %>
<% end %>
<%= translate(".missing", default: "Default") do |translation, key| %>
<%= key %>: <%= translation %>
<% end %>
<%= translate(".missing", default: "Default") do |translation| %>
<%= translation %>
<% end %>
<%= t('.missing') do |translation, key| %>
<%= key %>: <%= translation %>
<% end %>
<%= t('.missing') do |translation| %>
<%= translation %>
<% end %>
......@@ -20,6 +20,8 @@ class TranslationHelperTest < ActiveSupport::TestCase
translations: {
templates: {
found: { foo: "Foo" },
found_yield_single_argument: { foo: "Foo" },
found_yield_block: { foo: "Foo" },
array: { foo: { bar: "Foo Bar" } },
default: { foo: "Foo" }
},
......@@ -136,6 +138,14 @@ def test_finds_translation_scoped_by_partial
assert_equal "Foo", view.render(template: "translations/templates/found").strip
end
def test_finds_translation_scoped_by_partial_yielding_single_argument_block
assert_equal "Foo", view.render(template: "translations/templates/found_yield_single_argument").strip
end
def test_finds_translation_scoped_by_partial_yielding_translation_and_key
assert_equal "translations.templates.found_yield_block.foo: Foo", view.render(template: "translations/templates/found_yield_block").strip
end
def test_finds_array_of_translations_scoped_by_partial
assert_equal "Foo Bar", @view.render(template: "translations/templates/array").strip
end
......@@ -149,6 +159,26 @@ def test_missing_translation_scoped_by_partial
assert_equal expected, view.render(template: "translations/templates/missing").strip
end
def test_missing_translation_scoped_by_partial_yield_block
expected = 'translations.templates.missing_yield_block.missing: <span class="translation_missing" title="translation missing: en.translations.templates.missing_yield_block.missing">Missing</span>'
assert_equal expected, view.render(template: "translations/templates/missing_yield_block").strip
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
end
def test_missing_translation_scoped_by_partial_yield_single_argument_block
expected = '<span class="translation_missing" title="translation missing: en.translations.templates.missing_yield_single_argument_block.missing">Missing</span>'
assert_equal expected, view.render(template: "translations/templates/missing_yield_single_argument_block").strip
end
def test_missing_translation_with_default_scoped_by_partial_yield_single_argument_block
expected = "Default"
assert_equal expected, view.render(template: "translations/templates/missing_with_default_yield_single_argument_block").strip
end
def test_translate_does_not_mark_plain_text_as_safe_html
assert_equal false, translate(:'translations.hello').html_safe?
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册