Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make TranslationHelper#translate use the :rescue_format option in I18…

…n 0.5.0

Don't catch exceptions here. Instead only declare that we want exceptions to be rescued as :html, but also let users configure reactions to exceptions in I18n.

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information...
commit 896e25e994e272a1cb485d9a850501b488992cb2 1 parent 7ffd5da
@svenfuchs svenfuchs authored josevalim committed
View
32 actionpack/lib/action_view/helpers/translation_helper.rb
@@ -1,13 +1,33 @@
require 'action_view/helpers/tag_helper'
+require 'i18n/exceptions'
+
+module I18n
+ class ExceptionHandler
+ include Module.new {
+ def call(exception, locale, key, options)
+ exception.is_a?(MissingTranslationData) ? super.html_safe : super
+ end
+ }
+ end
+end
module ActionView
# = Action View Translation Helpers
module Helpers
module TranslationHelper
# Delegates to I18n#translate but also performs three additional functions.
- # First, it'll catch MissingTranslationData exceptions and turn them into
- # inline spans that contains the missing key, such that you can see in a
- # view what is missing where.
+ #
+ # First, it'll pass the :rescue_format => :html option to I18n so that any caught
+ # MissingTranslationData exceptions will be turned into inline spans that
+ #
+ # * have a "translation-missing" class set,
+ # * contain the missing key as a title attribute and
+ # * a titleized version of the last key segment as a text.
+ #
+ # E.g. the value returned for a missing translation key :"blog.post.title" will be
+ # <span class="translation_missing" title="translation missing: blog.post.title">Title</span>.
+ # This way your views will display rather reasonableful strings but it will still
+ # be easy to spot missing translations.
#
# Second, it'll scope the key by the current partial if the key starts
# with a period. So if you call <tt>translate(".foo")</tt> from the
@@ -24,15 +44,13 @@ module TranslationHelper
# naming convention helps to identify translations that include HTML tags so that
# you know what kind of output to expect when you call translate in a template.
def translate(key, options = {})
- translation = I18n.translate(scope_key_by_partial(key), options.merge!(:raise => true))
+ options.merge!(:rescue_format => :html) unless options.key?(:rescue_format)
+ translation = I18n.translate(scope_key_by_partial(key), options)
if html_safe_translation_key?(key) && translation.respond_to?(:html_safe)
translation.html_safe
else
translation
end
- rescue I18n::MissingTranslationData => e
- keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
- content_tag('span', keys.join(', '), :class => 'translation_missing')
end
alias :t :translate
View
1  actionpack/test/fixtures/test/scoped_translation.erb
@@ -1 +0,0 @@
-<%= t('.foo.bar').join %>
View
1  actionpack/test/fixtures/test/translation.erb
@@ -1 +0,0 @@
-<%= t('.helper') %>
View
1  actionpack/test/fixtures/translations/templates/array.erb
@@ -0,0 +1 @@
+<%= t('.foo.bar') %>
View
1  actionpack/test/fixtures/translations/templates/found.erb
@@ -0,0 +1 @@
+<%= t('.foo') %>
View
1  actionpack/test/fixtures/translations/templates/missing.erb
@@ -0,0 +1 @@
+<%= t('.missing') %>
View
67 actionpack/test/template/translation_helper_test.rb
@@ -4,60 +4,73 @@ class TranslationHelperTest < ActiveSupport::TestCase
include ActionView::Helpers::TagHelper
include ActionView::Helpers::TranslationHelper
- attr_reader :request
+ attr_reader :request, :view
+
def setup
+ I18n.backend.store_translations(:en,
+ :translations => {
+ :templates => {
+ :found => { :foo => 'Foo' },
+ :array => { :foo => { :bar => 'Foo Bar' } }
+ },
+ :foo => 'Foo',
+ :hello => '<a>Hello World</a>',
+ :html => '<a>Hello World</a>',
+ :hello_html => '<a>Hello World</a>',
+ :array_html => %w(foo bar),
+ :array => %w(foo bar)
+ }
+ )
+ @view = ::ActionView::Base.new(ActionController::Base.view_paths, {})
end
- def test_delegates_to_i18n_setting_the_raise_option
- I18n.expects(:translate).with(:foo, :locale => 'en', :raise => true).returns("")
+ def test_delegates_to_i18n_setting_the_rescue_format_option_to_html
+ I18n.expects(:translate).with(:foo, :locale => 'en', :rescue_format => :html).returns("")
translate :foo, :locale => 'en'
end
+ def test_delegates_localize_to_i18n
+ @time = Time.utc(2008, 7, 8, 12, 18, 38)
+ I18n.expects(:localize).with(@time)
+ localize @time
+ end
+
def test_returns_missing_translation_message_wrapped_into_span
- expected = '<span class="translation_missing">en, foo</span>'
- assert_equal expected, translate(:foo)
+ expected = '<span class="translation_missing" title="translation missing: en.translations.missing">Missing</span>'
+ assert_equal expected, translate(:"translations.missing")
end
def test_translation_returning_an_array
- I18n.expects(:translate).with(:foo, :raise => true).returns(["foo", "bar"])
- assert_equal ["foo", "bar"], translate(:foo)
+ expected = %w(foo bar)
+ assert_equal expected, translate(:"translations.array")
end
- def test_delegates_localize_to_i18n
- @time = Time.utc(2008, 7, 8, 12, 18, 38)
- I18n.expects(:localize).with(@time)
- localize @time
+ def test_finds_translation_scoped_by_partial
+ assert_equal 'Foo', view.render(:file => 'translations/templates/found').strip
end
- def test_scoping_by_partial
- I18n.expects(:translate).with("test.translation.helper", :raise => true).returns("helper")
- @view = ::ActionView::Base.new(ActionController::Base.view_paths, {})
- assert_equal "helper", @view.render(:file => "test/translation")
+ def test_finds_array_of_translations_scoped_by_partial
+ assert_equal 'Foo Bar', @view.render(:file => 'translations/templates/array').strip
end
- def test_scoping_by_partial_of_an_array
- I18n.expects(:translate).with("test.scoped_translation.foo.bar", :raise => true).returns(["foo", "bar"])
- @view = ::ActionView::Base.new(ActionController::Base.view_paths, {})
- assert_equal "foobar", @view.render(:file => "test/scoped_translation")
+ def test_missing_translation_scoped_by_partial
+ expected = '<span class="translation_missing" title="translation missing: en.translations.templates.missing.missing">Missing</span>'
+ assert_equal expected, view.render(:file => 'translations/templates/missing').strip
end
def test_translate_does_not_mark_plain_text_as_safe_html
- I18n.expects(:translate).with("hello", :raise => true).returns("Hello World")
- assert_equal false, translate("hello").html_safe?
+ assert_equal false, translate(:'translations.hello').html_safe?
end
def test_translate_marks_translations_named_html_as_safe_html
- I18n.expects(:translate).with("html", :raise => true).returns("<a>Hello World</a>")
- assert translate("html").html_safe?
+ assert translate(:'translations.html').html_safe?
end
def test_translate_marks_translations_with_a_html_suffix_as_safe_html
- I18n.expects(:translate).with("hello_html", :raise => true).returns("<a>Hello World</a>")
- assert translate("hello_html").html_safe?
+ assert translate(:'translations.hello_html').html_safe?
end
def test_translation_returning_an_array_ignores_html_suffix
- I18n.expects(:translate).with(:foo_html, :raise => true).returns(["foo", "bar"])
- assert_equal ["foo", "bar"], translate(:foo_html)
+ assert_equal ["foo", "bar"], translate(:'translations.array_html')
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.