aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md12
-rw-r--r--actionview/README.rdoc2
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb7
-rw-r--r--actionview/lib/action_view/helpers/atom_feed_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/cache_helper.rb22
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb63
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/translation_helper.rb12
-rw-r--r--actionview/test/template/asset_tag_helper_test.rb8
-rw-r--r--actionview/test/template/translation_helper_test.rb29
-rw-r--r--actionview/test/template/url_helper_test.rb10
11 files changed, 112 insertions, 59 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 78ce230b3a..a6d5c08fe9 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,15 @@
+* Remove `:rescue_format` option for `translate` helper since it's no longer
+ supported by I18n.
+
+ *Bernard Potocki*
+
+* `translate` should handle `raise` flag correctly in case of both main and default
+ translation is missing.
+
+ Fixes #19967
+
+ *Bernard Potocki*
+
* Load the `default_form_builder` from the controller on initialization, which overrides
the global config if it is present.
diff --git a/actionview/README.rdoc b/actionview/README.rdoc
index 5bb62c7562..8b1f85f748 100644
--- a/actionview/README.rdoc
+++ b/actionview/README.rdoc
@@ -9,7 +9,7 @@ used to inline short Ruby snippets inside HTML), and XML Builder.
The latest version of Action View can be installed with RubyGems:
- % [sudo] gem install actionview
+ % gem install actionview
Source code can be downloaded as part of the Rails project on GitHub
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 60fc9ee1a2..e32f8e219e 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -207,6 +207,7 @@ module ActionView
# # => <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
def image_tag(source, options={})
options = options.symbolize_keys
+ check_for_image_tag_errors(options)
src = options[:src] = path_to_image(source)
@@ -325,6 +326,12 @@ module ActionView
[size, size]
end
end
+
+ def check_for_image_tag_errors(options)
+ if options[:size] && (options[:height] || options[:width])
+ raise ArgumentError, "Cannot pass a :size option with a :height or :width option"
+ end
+ end
end
end
end
diff --git a/actionview/lib/action_view/helpers/atom_feed_helper.rb b/actionview/lib/action_view/helpers/atom_feed_helper.rb
index d8be4e5678..bb1cdd0f8d 100644
--- a/actionview/lib/action_view/helpers/atom_feed_helper.rb
+++ b/actionview/lib/action_view/helpers/atom_feed_helper.rb
@@ -16,7 +16,7 @@ module ActionView
# end
#
# app/controllers/posts_controller.rb:
- # class PostsController < ApplicationController::Base
+ # class PostsController < ApplicationController
# # GET /posts.html
# # GET /posts.atom
# def index
@@ -51,7 +51,7 @@ module ActionView
# * <tt>:language</tt>: Defaults to "en-US".
# * <tt>:root_url</tt>: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
# * <tt>:url</tt>: The URL for this feed. Defaults to the current URL.
- # * <tt>:id</tt>: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}"
+ # * <tt>:id</tt>: The id for this feed. Defaults to "tag:localhost,2005:/posts", in this case.
# * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
# created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
# 2005 is used (as an "I don't care" value).
diff --git a/actionview/lib/action_view/helpers/cache_helper.rb b/actionview/lib/action_view/helpers/cache_helper.rb
index 0e2a5f90f4..251764a8de 100644
--- a/actionview/lib/action_view/helpers/cache_helper.rb
+++ b/actionview/lib/action_view/helpers/cache_helper.rb
@@ -75,7 +75,8 @@ module ActionView
# render(topics) => render("topics/topic")
# render(message.topics) => render("topics/topic")
#
- # It's not possible to derive all render calls like that, though. Here are a few examples of things that can't be derived:
+ # It's not possible to derive all render calls like that, though.
+ # Here are a few examples of things that can't be derived:
#
# render group_of_attachments
# render @project.documents.where(published: true).order('created_at')
@@ -97,19 +98,21 @@ module ActionView
# <%# Template Dependency: todolists/todolist %>
# <%= render_sortable_todolists @project.todolists %>
#
- # The pattern used to match these is /# Template Dependency: ([^ ]+)/, so it's important that you type it out just so.
+ # The pattern used to match these is /# Template Dependency: ([^ ]+)/,
+ # so it's important that you type it out just so.
# You can only declare one template dependency per line.
#
# === External dependencies
#
- # If you use a helper method, for example, inside of a cached block and you then update that helper,
- # you'll have to bump the cache as well. It doesn't really matter how you do it, but the md5 of the template file
+ # If you use a helper method, for example, inside a cached block and
+ # you then update that helper, you'll have to bump the cache as well.
+ # It doesn't really matter how you do it, but the md5 of the template file
# must change. One recommendation is to simply be explicit in a comment, like:
#
# <%# Helper Dependency Updated: May 6, 2012 at 6pm %>
# <%= some_helper_method(person) %>
#
- # Now all you'll have to do is change that timestamp when the helper method changes.
+ # Now all you have to do is change that timestamp when the helper method changes.
#
# === Automatic Collection Caching
#
@@ -118,7 +121,7 @@ module ActionView
# <%= render @notifications %>
# <%= render partial: 'notifications/notification', collection: @notifications %>
#
- # If the notifications/_notification partial starts with a cache call like so:
+ # If the notifications/_notification partial starts with a cache call as:
#
# <% cache notification do %>
# <%= notification.name %>
@@ -127,14 +130,15 @@ module ActionView
# The collection can then automatically use any cached renders for that
# template by reading them at once instead of one by one.
#
- # See ActionView::Template::Handlers::ERB.resource_cache_call_pattern for more
- # information on what cache calls make a template eligible for this collection caching.
+ # See ActionView::Template::Handlers::ERB.resource_cache_call_pattern for
+ # more information on what cache calls make a template eligible for this
+ # collection caching.
#
# The automatic cache multi read can be turned off like so:
#
# <%= render @notifications, cache: false %>
def cache(name = {}, options = nil, &block)
- if controller.perform_caching
+ if controller.respond_to?(:perform_caching) && controller.perform_caching
safe_concat(fragment_for(cache_fragment_name(name, options), options, &block))
else
yield
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 7fdeca5ea8..3a9acafaa2 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -1631,7 +1631,7 @@ module ActionView
# target labels for radio_button tags (where the value is used in the ID of the input tag).
#
# ==== Examples
- # label(:post, :title)
+ # label(:title)
# # => <label for="post_title">Title</label>
#
# You can localize your labels based on model and attribute names.
@@ -1644,7 +1644,7 @@ module ActionView
#
# Which then will result in
#
- # label(:post, :body)
+ # label(:body)
# # => <label for="post_body">Write your entire text here</label>
#
# Localization can also be based purely on the translation of the attribute-name
@@ -1655,21 +1655,22 @@ module ActionView
# post:
# cost: "Total cost"
#
- # label(:post, :cost)
+ # label(:cost)
# # => <label for="post_cost">Total cost</label>
#
- # label(:post, :title, "A short title")
+ # label(:title, "A short title")
# # => <label for="post_title">A short title</label>
#
- # label(:post, :title, "A short title", class: "title_label")
+ # label(:title, "A short title", class: "title_label")
# # => <label for="post_title" class="title_label">A short title</label>
#
- # label(:post, :privacy, "Public Post", value: "public")
+ # label(:privacy, "Public Post", value: "public")
# # => <label for="post_privacy_public">Public Post</label>
#
- # label(:post, :terms) do
+ # label(:terms) do
# 'Accept <a href="/terms">Terms</a>.'.html_safe
# end
+ # # => <label for="post_terms">Accept <a href="/terms">Terms</a>.</label>
def label(method, text = nil, options = {}, &block)
@template.label(@object_name, method, text, objectify_options(options), &block)
end
@@ -1718,16 +1719,17 @@ module ActionView
# hashes instead of arrays.
#
# # Let's say that @post.validated? is 1:
- # check_box("post", "validated")
+ # check_box("validated")
# # => <input name="post[validated]" type="hidden" value="0" />
# # <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
#
# # Let's say that @puppy.gooddog is "no":
- # check_box("puppy", "gooddog", {}, "yes", "no")
+ # check_box("gooddog", {}, "yes", "no")
# # => <input name="puppy[gooddog]" type="hidden" value="no" />
# # <input type="checkbox" id="puppy_gooddog" name="puppy[gooddog]" value="yes" />
#
- # check_box("eula", "accepted", { class: 'eula_check' }, "yes", "no")
+ # # Let's say that @eula.accepted is "no":
+ # check_box("accepted", { class: 'eula_check' }, "yes", "no")
# # => <input name="eula[accepted]" type="hidden" value="no" />
# # <input type="checkbox" class="eula_check" id="eula_accepted" name="eula[accepted]" value="yes" />
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
@@ -1742,13 +1744,14 @@ module ActionView
# +options+ hash. You may pass HTML options there as well.
#
# # Let's say that @post.category returns "rails":
- # radio_button("post", "category", "rails")
- # radio_button("post", "category", "java")
+ # radio_button("category", "rails")
+ # radio_button("category", "java")
# # => <input type="radio" id="post_category_rails" name="post[category]" value="rails" checked="checked" />
# # <input type="radio" id="post_category_java" name="post[category]" value="java" />
#
- # radio_button("user", "receive_newsletter", "yes")
- # radio_button("user", "receive_newsletter", "no")
+ # # Let's say that @user.category returns "no":
+ # radio_button("receive_newsletter", "yes")
+ # radio_button("receive_newsletter", "no")
# # => <input type="radio" id="user_receive_newsletter_yes" name="user[receive_newsletter]" value="yes" />
# # <input type="radio" id="user_receive_newsletter_no" name="user[receive_newsletter]" value="no" checked="checked" />
def radio_button(method, tag_value, options = {})
@@ -1761,14 +1764,17 @@ module ActionView
# shown.
#
# ==== Examples
- # hidden_field(:signup, :pass_confirm)
- # # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="#{@signup.pass_confirm}" />
+ # # Let's say that @signup.pass_confirm returns true:
+ # hidden_field(:pass_confirm)
+ # # => <input type="hidden" id="signup_pass_confirm" name="signup[pass_confirm]" value="true" />
#
- # hidden_field(:post, :tag_list)
- # # => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="#{@post.tag_list}" />
+ # # Let's say that @post.tag_list returns "blog, ruby":
+ # hidden_field(:tag_list)
+ # # => <input type="hidden" id="post_tag_list" name="post[tag_list]" value="blog, ruby" />
#
- # hidden_field(:user, :token)
- # # => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
+ # # Let's say that @user.token returns "abcde":
+ # hidden_field(:token)
+ # # => <input type="hidden" id="user_token" name="user[token]" value="abcde" />
#
def hidden_field(method, options = {})
@emitted_hidden_id = true if method == :id
@@ -1789,19 +1795,24 @@ module ActionView
# * <tt>:accept</tt> - If set to one or multiple mime-types, the user will be suggested a filter when choosing a file. You still need to set up model validations.
#
# ==== Examples
- # file_field(:user, :avatar)
+ # # Let's say that @user has avatar:
+ # file_field(:avatar)
# # => <input type="file" id="user_avatar" name="user[avatar]" />
#
- # file_field(:post, :image, :multiple => true)
- # # => <input type="file" id="post_image" name="post[image]" multiple="true" />
+ # # Let's say that @post has image:
+ # file_field(:image, :multiple => true)
+ # # => <input type="file" id="post_image" name="post[image][]" multiple="multiple" />
#
- # file_field(:post, :attached, accept: 'text/html')
+ # # Let's say that @post has attached:
+ # file_field(:attached, accept: 'text/html')
# # => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
#
- # file_field(:post, :image, accept: 'image/png,image/gif,image/jpeg')
+ # # Let's say that @post has image:
+ # file_field(:image, accept: 'image/png,image/gif,image/jpeg')
# # => <input type="file" id="post_image" name="post[image]" accept="image/png,image/gif,image/jpeg" />
#
- # file_field(:attachment, :file, class: 'file_input')
+ # # Let's say that @attachment has file:
+ # file_field(:file, class: 'file_input')
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
def file_field(method, options = {})
self.multipart = true
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index 8a5928477f..38fee3b314 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -80,7 +80,7 @@ module ActionView
#
# When used with the <tt>collection_select</tt> helper, <tt>:disabled</tt> can also be a Proc that identifies those options that should be disabled.
#
- # collection_select(:post, :category_id, Category.all, :id, :name, {disabled: lambda{|category| category.archived? }})
+ # collection_select(:post, :category_id, Category.all, :id, :name, {disabled: -> (category) { category.archived? }})
#
# If the categories "2008 stuff" and "Christmas" return true when the method <tt>archived?</tt> is called, this would return:
# <select name="post[category_id]" id="post_category_id">
diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb
index 089627a221..0615bd2e0d 100644
--- a/actionview/lib/action_view/helpers/translation_helper.rb
+++ b/actionview/lib/action_view/helpers/translation_helper.rb
@@ -60,12 +60,12 @@ module ActionView
# If the user has explicitly decided to NOT raise errors, pass that option to I18n.
# Otherwise, tell I18n to raise an exception, which we rescue further in this method.
# Note: `raise_error` refers to us re-raising the error in this method. I18n is forced to raise by default.
- if options[:raise] == false || (options.key?(:rescue_format) && options[:rescue_format].nil?)
+ if options[:raise] == false
raise_error = false
- options[:raise] = false
+ i18n_raise = false
else
- raise_error = options[:raise] || options[:rescue_format] || ActionView::Base.raise_on_missing_translations
- options[:raise] = true
+ raise_error = options[:raise] || ActionView::Base.raise_on_missing_translations
+ i18n_raise = true
end
if html_safe_translation_key?(key)
@@ -75,11 +75,11 @@ module ActionView
html_safe_options[name] = ERB::Util.html_escape(value.to_s)
end
end
- translation = I18n.translate(scope_key_by_partial(key), html_safe_options)
+ translation = I18n.translate(scope_key_by_partial(key), html_safe_options.merge(raise: i18n_raise))
translation.respond_to?(:html_safe) ? translation.html_safe : translation
else
- I18n.translate(scope_key_by_partial(key), options)
+ I18n.translate(scope_key_by_partial(key), options.merge(raise: i18n_raise))
end
rescue I18n::MissingTranslationData => e
if remaining_defaults.present?
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index 02dce71496..6e6ce20924 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -464,6 +464,14 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal({:size => '16x10'}, options)
end
+ def test_image_tag_raises_an_error_for_competing_size_arguments
+ exception = assert_raise(ArgumentError) do
+ image_tag("gold.png", :height => "100", :width => "200", :size => "45x70")
+ end
+
+ assert_equal("Cannot pass a :size option with a :height or :width option", exception.message)
+ end
+
def test_favicon_link_tag
FaviconLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index df096b3c3a..5dc281adb2 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -41,8 +41,8 @@ class TranslationHelperTest < ActiveSupport::TestCase
I18n.backend.reload!
end
- def test_delegates_to_i18n_setting_the_rescue_format_option_to_html
- I18n.expects(:translate).with(:foo, :locale => 'en', :raise=>true).returns("")
+ def test_delegates_setting_to_i18n
+ I18n.expects(:translate).with(:foo, :locale => 'en', :raise => true).returns("")
translate :foo, :locale => 'en'
end
@@ -58,12 +58,6 @@ class TranslationHelperTest < ActiveSupport::TestCase
assert_equal true, translate(:"translations.missing").html_safe?
end
- def test_returns_missing_translation_message_using_nil_as_rescue_format
- expected = 'translation missing: en.translations.missing'
- assert_equal expected, translate(:"translations.missing", :rescue_format => nil)
- assert_equal false, translate(:"translations.missing", :rescue_format => nil).html_safe?
- end
-
def test_raises_missing_translation_message_with_raise_config_option
ActionView::Base.raise_on_missing_translations = true
@@ -96,12 +90,6 @@ class TranslationHelperTest < ActiveSupport::TestCase
I18n.exception_handler = old_exception_handler
end
- def test_i18n_translate_defaults_to_nil_rescue_format
- expected = 'translation missing: en.translations.missing'
- assert_equal expected, I18n.translate(:"translations.missing")
- assert_equal false, I18n.translate(:"translations.missing").html_safe?
- end
-
def test_translation_returning_an_array
expected = %w(foo bar)
assert_equal expected, translate(:"translations.array")
@@ -157,6 +145,19 @@ class TranslationHelperTest < ActiveSupport::TestCase
assert_equal true, translation.html_safe?
end
+ def test_translate_with_missing_default
+ translation = translate(:'translations.missing', :default => :'translations.missing_html')
+ expected = '<span class="translation_missing" title="translation missing: en.translations.missing_html">Missing Html</span>'
+ assert_equal expected, translation
+ assert_equal true, translation.html_safe?
+ end
+
+ def test_translate_with_missing_default_and_raise_option
+ assert_raise(I18n::MissingTranslationData) do
+ translate(:'translations.missing', :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
diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb
index ef4df0407a..0e35c67516 100644
--- a/actionview/test/template/url_helper_test.rb
+++ b/actionview/test/template/url_helper_test.rb
@@ -379,6 +379,11 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_dom_equal %{<a href="/">Listing</a>}, link_to_if(true, "Listing", url_hash)
end
+ def test_link_to_if_with_block
+ assert_equal "Fallback", link_to_if(false, "Showing", url_hash) { "Fallback" }
+ assert_dom_equal %{<a href="/">Listing</a>}, link_to_if(true, "Listing", url_hash) { "Fallback" }
+ end
+
def request_for_url(url, opts = {})
env = Rack::MockRequest.env_for("http://www.example.com#{url}", opts)
ActionDispatch::Request.new(env)
@@ -479,6 +484,11 @@ class UrlHelperTest < ActiveSupport::TestCase
link_to_unless_current("Listing", "http://www.example.com/")
end
+ def test_link_to_unless_with_block
+ assert_dom_equal %{<a href="/">Showing</a>}, link_to_unless(false, "Showing", url_hash) { "Fallback" }
+ assert_equal "Fallback", link_to_unless(true, "Listing", url_hash) { "Fallback" }
+ end
+
def test_mail_to
assert_dom_equal %{<a href="mailto:david@loudthinking.com">david@loudthinking.com</a>}, mail_to("david@loudthinking.com")
assert_dom_equal %{<a href="mailto:david@loudthinking.com">David Heinemeier Hansson</a>}, mail_to("david@loudthinking.com", "David Heinemeier Hansson")