From 68a207ccf6dffa58c9a9a3e221b99af72859ce27 Mon Sep 17 00:00:00 2001 From: Yehuda Katz + Carl Lerche Date: Thu, 21 May 2009 18:14:20 -0700 Subject: [PATCH] Implemented layout conditions in new base --- .../lib/action_controller/abstract/layouts.rb | 25 +++++++++++++++--- actionpack/test/controller/layout_test.rb | 26 ++++++++++++------- .../layouts/third_party_template_library.mab | 2 +- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 96cb05972f..557d68d866 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -4,11 +4,19 @@ module AbstractController depends_on Renderer + included do + extlib_inheritable_accessor :_layout_conditions + self._layout_conditions = {} + end + module ClassMethods - def layout(layout) + def layout(layout, conditions = {}) unless [String, Symbol, FalseClass, NilClass].include?(layout.class) raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" end + + conditions.each {|k, v| conditions[k] = Array(v).map {|a| a.to_s} } + self._layout_conditions = conditions @_layout = layout || false # Converts nil to false _write_layout_method @@ -75,17 +83,28 @@ module AbstractController end def _default_layout(require_layout = false) - if require_layout && !_layout + if require_layout && _action_has_layout? && !_layout raise ArgumentError, "There was no default layout for #{self.class} in #{view_paths.inspect}" end begin - layout = _layout_for_name(_layout) + _layout_for_name(_layout) if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end end + + def _action_has_layout? + conditions = _layout_conditions + if only = conditions[:only] + only.include?(action_name) + elsif except = conditions[:except] + !except.include?(action_name) + else + true + end + end end end \ No newline at end of file diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 5b7d40d16d..1cd448d5e8 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -9,8 +9,11 @@ ActionView::Template::register_template_handler :mab, ActionController::Base.view_paths = [ File.dirname(__FILE__) + '/../fixtures/layout_tests/' ] +require "lib/fixture_template" + class LayoutTest < ActionController::Base def self.controller_path; 'views' end + def self._implied_layout_name; to_s.underscore.gsub(/_controller$/, '') ; end self.view_paths = ActionController::Base.view_paths.dup end @@ -35,6 +38,15 @@ end class MultipleExtensions < LayoutTest end +if defined?(ActionController::Http) + LayoutTest._write_layout_method + ProductController._write_layout_method + ItemController._write_layout_method + ThirdPartyTemplateLibraryController._write_layout_method + MultipleExtensions._write_layout_method + ControllerNameSpace::NestedController._write_layout_method +end + class LayoutAutoDiscoveryTest < ActionController::TestCase def setup super @@ -56,23 +68,19 @@ class LayoutAutoDiscoveryTest < ActionController::TestCase def test_third_party_template_library_auto_discovers_layout @controller = ThirdPartyTemplateLibraryController.new get :hello - assert @controller.active_layout(true).identifier.include?('layouts/third_party_template_library.mab') - assert @controller.template.layout.include?('layouts/third_party_template_library') assert_response :success - assert_equal 'Mab', @response.body + assert_equal 'layouts/third_party_template_library.mab', @response.body end - def test_namespaced_controllers_auto_detect_layouts + def test_namespaced_controllers_auto_detect_layouts1 @controller = ControllerNameSpace::NestedController.new get :hello - assert_equal 'layouts/controller_name_space/nested', @controller.active_layout(true).to_s assert_equal 'controller_name_space/nested.rhtml hello.rhtml', @response.body end - def test_namespaced_controllers_auto_detect_layouts + def test_namespaced_controllers_auto_detect_layouts2 @controller = MultipleExtensions.new get :hello - assert @controller.active_layout(true).identifier.include?('layouts/multiple_extensions.html.erb') assert_equal 'multiple_extensions.html.erb hello.rhtml', @response.body.strip end end @@ -139,7 +147,7 @@ class LayoutSetInResponseTest < ActionController::TestCase def test_layout_only_exception_when_excepted @controller = OnlyLayoutController.new get :goodbye - assert_equal nil, @controller.template.layout + assert !@response.body.include?("item.rhtml"), "#{@response.body.inspect} included 'item.rhtml'" end def test_layout_except_exception_when_included @@ -151,7 +159,7 @@ class LayoutSetInResponseTest < ActionController::TestCase def test_layout_except_exception_when_excepted @controller = ExceptLayoutController.new get :goodbye - assert_equal nil, @controller.template.layout + assert !@response.body.include?("item.rhtml"), "#{@response.body.inspect} included 'item.rhtml'" end def test_layout_set_when_using_render diff --git a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab b/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab index 018abfb0ac..fcee620d82 100644 --- a/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab +++ b/actionpack/test/fixtures/layout_tests/layouts/third_party_template_library.mab @@ -1 +1 @@ -Mab \ No newline at end of file +layouts/third_party_template_library.mab \ No newline at end of file