diff options
Diffstat (limited to 'actionview')
-rw-r--r-- | actionview/CHANGELOG.md | 22 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/form_helper.rb | 6 | ||||
-rw-r--r-- | actionview/lib/action_view/helpers/translation_helper.rb | 3 | ||||
-rw-r--r-- | actionview/lib/action_view/routing_url_for.rb | 8 | ||||
-rw-r--r-- | actionview/lib/action_view/template/resolver.rb | 28 | ||||
-rw-r--r-- | actionview/lib/action_view/view_paths.rb | 41 | ||||
-rw-r--r-- | actionview/test/actionpack/abstract/abstract_controller_test.rb | 48 | ||||
-rw-r--r-- | actionview/test/activerecord/polymorphic_routes_test.rb | 85 | ||||
-rw-r--r-- | actionview/test/template/sanitize_helper_test.rb | 2 | ||||
-rw-r--r-- | actionview/test/template/test_test.rb | 2 | ||||
-rw-r--r-- | actionview/test/template/translation_helper_test.rb | 6 |
11 files changed, 205 insertions, 46 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 36028122d1..147e5b47db 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,4 +1,15 @@ -* Take label values into account when doing I18n lookups for model attributes. +* Allow custom `:host` option to be passed to `asset_url` helper that + overwrites `config.action_controller.asset_host` for particular asset. + + *Hubert Łępicki* + +* Deprecate `AbstractController::Base.parent_prefixes`. + Override `AbstractController::Base.local_prefixes` when you want to change + where to find views. + + *Nick Sutterer* + +* Take label values into account when doing I18n lookups for model attributes. The following: @@ -20,9 +31,11 @@ * Change `asset_path` to use File.join to create proper paths: + Before: + https://some.host.com//assets/some.js - becomes + After: https://some.host.com/assets/some.js @@ -87,9 +100,4 @@ *Piotr Chmolowski, Łukasz Strzałkowski* -* Allow custom `:host` option to be passed to `asset_url` helper that - overwrites `config.action_controller.asset_host` for particular asset. - - *Hubert Łępicki* - Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionview/CHANGELOG.md) for previous changes. diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb index 22bfd87d85..180c4a62bf 100644 --- a/actionview/lib/action_view/helpers/form_helper.rb +++ b/actionview/lib/action_view/helpers/form_helper.rb @@ -449,7 +449,11 @@ module ActionView method: method ) - options[:url] ||= polymorphic_path(record, format: options.delete(:format)) + options[:url] ||= if options.key?(:format) + polymorphic_path(record, format: options.delete(:format)) + else + polymorphic_path(record, {}) + end end private :apply_form_for_options! diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb index 0bc40874d9..17ec6a40bf 100644 --- a/actionview/lib/action_view/helpers/translation_helper.rb +++ b/actionview/lib/action_view/helpers/translation_helper.rb @@ -7,7 +7,7 @@ module ActionView module TranslationHelper # Delegates to <tt>I18n#translate</tt> but also performs three additional functions. # - # First, it will ensure that any thrown +MissingTranslation+ messages will be turned + # First, it will ensure that any thrown +MissingTranslation+ messages will be turned # into inline spans that: # # * have a "translation-missing" class set, @@ -34,6 +34,7 @@ module ActionView # 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 = {}) + options = options.dup options[:default] = wrap_translate_defaults(options[:default]) if options[:default] # If the user has specified rescue_format then pass it all through, otherwise use diff --git a/actionview/lib/action_view/routing_url_for.rb b/actionview/lib/action_view/routing_url_for.rb index b9e4b590e7..881a123572 100644 --- a/actionview/lib/action_view/routing_url_for.rb +++ b/actionview/lib/action_view/routing_url_for.rb @@ -1,3 +1,5 @@ +require 'action_dispatch/routing/polymorphic_routes' + module ActionView module RoutingUrlFor @@ -83,10 +85,14 @@ module ActionView super({ :only_path => options[:host].nil? }.merge!(options.symbolize_keys)) when :back _back_url + when Symbol + ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_string_call self, options when Array polymorphic_path(options, options.extract_options!) + when Class + ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_class_call self, options else - polymorphic_path(options) + ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.path.handle_model_call self, options end end diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb index 05f0c301e7..189086132e 100644 --- a/actionview/lib/action_view/template/resolver.rb +++ b/actionview/lib/action_view/template/resolver.rb @@ -181,13 +181,7 @@ module ActionView def query(path, details, formats) query = build_query(path, details) - # deals with case-insensitive file systems. - sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] } - - template_paths = Dir[query].reject { |filename| - File.directory?(filename) || - !sanitizer[File.dirname(filename)].include?(filename) - } + template_paths = find_template_paths query template_paths.map { |template| handler, format, variant = extract_handler_and_format_and_variant(template, formats) @@ -202,6 +196,26 @@ module ActionView } end + if File.const_defined? :FNM_EXTGLOB + def find_template_paths(query) + Dir[query].reject { |filename| + File.directory?(filename) || + # deals with case-insensitive file systems. + !File.fnmatch(query, filename, File::FNM_EXTGLOB) + } + end + else + def find_template_paths(query) + # deals with case-insensitive file systems. + sanitizer = Hash.new { |h,dir| h[dir] = Dir["#{dir}/*"] } + + Dir[query].reject { |filename| + File.directory?(filename) || + !sanitizer[File.dirname(filename)].include?(filename) + } + end + end + # Helper for building query glob string based on resolver's pattern. def build_query(path, details) query = @pattern.dup diff --git a/actionview/lib/action_view/view_paths.rb b/actionview/lib/action_view/view_paths.rb index 6c349feb1d..80a41f2418 100644 --- a/actionview/lib/action_view/view_paths.rb +++ b/actionview/lib/action_view/view_paths.rb @@ -14,27 +14,38 @@ module ActionView :locale, :locale=, :to => :lookup_context module ClassMethods - def parent_prefixes - @parent_prefixes ||= begin - parent_controller = superclass - prefixes = [] - - until parent_controller.abstract? - prefixes << parent_controller.controller_path - parent_controller = parent_controller.superclass - end + def _prefixes # :nodoc: + @_prefixes ||= begin + deprecated_prefixes = handle_deprecated_parent_prefixes + if deprecated_prefixes + deprecated_prefixes + else + return local_prefixes if superclass.abstract? - prefixes + local_prefixes + superclass._prefixes + end end end + + private + + # Override this method in your controller if you want to change paths prefixes for finding views. + # Prefixes defined here will still be added to parents' <tt>._prefixes</tt>. + def local_prefixes + [controller_path] + end + + def handle_deprecated_parent_prefixes # TODO: remove in 4.3/5.0. + return unless respond_to?(:parent_prefixes) + + ActiveSupport::Deprecation.warn "Overriding ActionController::Base::parent_prefixes is deprecated, override .local_prefixes instead." + local_prefixes + parent_prefixes + end end # The prefixes used in render "foo" shortcuts. - def _prefixes - @_prefixes ||= begin - parent_prefixes = self.class.parent_prefixes - parent_prefixes.dup.unshift(controller_path) - end + def _prefixes # :nodoc: + self.class._prefixes end # LookupContext is the object responsible to hold all information required to lookup diff --git a/actionview/test/actionpack/abstract/abstract_controller_test.rb b/actionview/test/actionpack/abstract/abstract_controller_test.rb index 40d3b17131..e653b12d32 100644 --- a/actionview/test/actionpack/abstract/abstract_controller_test.rb +++ b/actionview/test/actionpack/abstract/abstract_controller_test.rb @@ -150,6 +150,54 @@ module AbstractController end end + class OverridingLocalPrefixes < AbstractController::Base + include AbstractController::Rendering + include ActionView::Rendering + append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) + + def index + render + end + + def self.local_prefixes + # this would usually return "abstract_controller/testing/overriding_local_prefixes" + super + ["abstract_controller/testing/me3"] + end + + class Inheriting < self + end + end + + class OverridingLocalPrefixesTest < ActiveSupport::TestCase # TODO: remove me in 5.0/4.3. + test "overriding .local_prefixes adds prefix" do + @controller = OverridingLocalPrefixes.new + @controller.process(:index) + assert_equal "Hello from me3/index.erb", @controller.response_body + end + + test ".local_prefixes is inherited" do + @controller = OverridingLocalPrefixes::Inheriting.new + @controller.process(:index) + assert_equal "Hello from me3/index.erb", @controller.response_body + end + end + + class DeprecatedParentPrefixes < OverridingLocalPrefixes + def self.parent_prefixes + ["abstract_controller/testing/me3"] + end + end + + class DeprecatedParentPrefixesTest < ActiveSupport::TestCase # TODO: remove me in 5.0/4.3. + test "overriding .parent_prefixes is deprecated" do + @controller = DeprecatedParentPrefixes.new + assert_deprecated do + @controller.process(:index) + end + assert_equal "Hello from me3/index.erb", @controller.response_body + end + end + # Test rendering with layouts # ==== # self._layout is used when defined diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb index a42888d873..fef27ef492 100644 --- a/actionview/test/activerecord/polymorphic_routes_test.rb +++ b/actionview/test/activerecord/polymorphic_routes_test.rb @@ -75,6 +75,9 @@ class PolymorphicRoutesTest < ActionController::TestCase end def assert_url(url, args) + host = self.class.default_url_options[:host] + + assert_equal url.sub(/http:\/\/#{host}/, ''), polymorphic_path(args) assert_equal url, polymorphic_url(args) assert_equal url, url_for(args) end @@ -96,8 +99,7 @@ class PolymorphicRoutesTest < ActionController::TestCase def test_symbol with_test_routes do - assert_equal "http://example.com/projects", polymorphic_url(:projects) - assert_equal "http://example.com/projects", url_for(:projects) + assert_url "http://example.com/projects", :projects end end @@ -129,6 +131,23 @@ class PolymorphicRoutesTest < ActionController::TestCase end end + def test_polymorphic_url_with_2_objects + with_namespaced_routes(:blog) do + @blog_blog.save + @blog_post.save + assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}", polymorphic_url([@blog_blog, @blog_post]) + end + end + + def test_polymorphic_url_with_3_objects + with_namespaced_routes(:blog) do + @blog_blog.save + @blog_post.save + @fax.save + assert_equal "http://example.com/blogs/#{@blog_blog.id}/posts/#{@blog_post.id}/faxes/#{@fax.id}", polymorphic_url([@blog_blog, @blog_post, @fax]) + end + end + def test_namespaced_model_with_nested_resources with_namespaced_routes(:blog) do @blog_post.save @@ -183,6 +202,19 @@ class PolymorphicRoutesTest < ActionController::TestCase end end + def test_with_class_list_of_one + with_test_routes do + assert_url "http://example.com/projects", [@project.class] + end + end + + def test_class_with_options + with_test_routes do + assert_equal "http://example.com/projects?foo=bar", polymorphic_url(@project.class, { :foo => :bar }) + assert_equal "/projects?foo=bar", polymorphic_path(@project.class, { :foo => :bar }) + end + end + def test_with_new_record with_test_routes do assert_url "http://example.com/projects", @project @@ -191,14 +223,20 @@ class PolymorphicRoutesTest < ActionController::TestCase def test_new_record_arguments params = nil - extend Module.new { - define_method("projects_url") { |*args| - params = args - super(*args) - } - } with_test_routes do + extend Module.new { + define_method("projects_url") { |*args| + params = args + super(*args) + } + + define_method("projects_path") { |*args| + params = args + super(*args) + } + } + assert_url "http://example.com/projects", @project assert_equal [], params end @@ -389,6 +427,12 @@ class PolymorphicRoutesTest < ActionController::TestCase end end + def test_with_array_containing_single_string_name + with_test_routes do + assert_url "http://example.com/projects", ["projects"] + end + end + def test_with_array_containing_symbols with_test_routes do assert_url "http://example.com/series/new", [:new, :series] @@ -543,13 +587,15 @@ class PolymorphicRoutesTest < ActionController::TestCase set.draw do scope(:module => name) do resources :blogs do - resources :posts + resources :posts do + resources :faxes + end end resources :posts end end - self.class.send(:include, @routes.url_helpers) + extend @routes.url_helpers yield end end @@ -571,7 +617,7 @@ class PolymorphicRoutesTest < ActionController::TestCase resources :model_delegates end - self.class.send(:include, @routes.url_helpers) + extend @routes.url_helpers yield end end @@ -593,7 +639,7 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - self.class.send(:include, @routes.url_helpers) + extend @routes.url_helpers yield end end @@ -612,8 +658,21 @@ class PolymorphicRoutesTest < ActionController::TestCase end end - self.class.send(:include, @routes.url_helpers) + extend @routes.url_helpers yield end end end + +class PolymorphicPathRoutesTest < PolymorphicRoutesTest + include ActionView::RoutingUrlFor + include ActionView::Context + + attr_accessor :controller + + def assert_url(url, args) + host = self.class.default_url_options[:host] + + assert_equal url.sub(/http:\/\/#{host}/, ''), url_for(args) + end +end diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb index 12d5260a9d..f7c8f36b78 100644 --- a/actionview/test/template/sanitize_helper_test.rb +++ b/actionview/test/template/sanitize_helper_test.rb @@ -1,6 +1,6 @@ require 'abstract_unit' -# The exhaustive tests are in test/controller/html/sanitizer_test.rb. +# The exhaustive tests are in test/template/html-scanner/sanitizer_test.rb # This tests the that the helpers hook up correctly to the sanitizer classes. class SanitizeHelperTest < ActionView::TestCase tests ActionView::Helpers::SanitizeHelper diff --git a/actionview/test/template/test_test.rb b/actionview/test/template/test_test.rb index 5721ee6c6f..88bac85039 100644 --- a/actionview/test/template/test_test.rb +++ b/actionview/test/template/test_test.rb @@ -39,6 +39,8 @@ class PeopleHelperTest < ActionView::TestCase with_test_route_set do person = Struct.new(:name) { extend ActiveModel::Naming + def to_model; self; end + def persisted?; true; end def self.name; 'Mocha::Mock'; end }.new "David" diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb index c4770840fb..a9d5ea7345 100644 --- a/actionview/test/template/translation_helper_test.rb +++ b/actionview/test/template/translation_helper_test.rb @@ -151,4 +151,10 @@ class TranslationHelperTest < ActiveSupport::TestCase translation = translate(:'translations.missing', default: ['A Generic String', 'Second generic string']) assert_equal 'A Generic String', translation end + + def test_translate_does_not_change_options + options = {} + translate(:'translations.missing', options) + assert_equal({}, options) + end end |