From ffe1f9d2f2da2232d6334931bac52f3108fef258 Mon Sep 17 00:00:00 2001 From: Neeraj Singh Date: Sat, 15 May 2010 13:33:37 -0400 Subject: [PATCH] layout should accept symbol as layout name [#4608 state:resolved] --- actionpack/lib/abstract_controller/layouts.rb | 30 ++++++++++++++++-------- actionpack/test/abstract/layouts_test.rb | 19 ++++++++++++++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 319472c..307551a 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -87,6 +87,17 @@ module AbstractController # The TellerController uses +teller.html.erb+, and TillController inherits that layout and # uses it as well. # + # layout name can be assigned as a string or as a symbol. If a layout name is a symbol then first an attempt + # is made to get the layout name by invoking method by the name supplied in the layout. If no such method is found + # then a layout by that name is applied. + # + # class BankController < ActionController::Base + # layout :bank_standard + # end + # + # In the above case first it is checked if controller has a method named "bank_standard". If no such + # method is found then layout named "bank_standard" is applied. + # # == Types of layouts # # Layouts are basically just regular templates, but the name of this template needs not be specified statically. Sometimes @@ -249,11 +260,15 @@ module AbstractController when Symbol self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 def _layout - #{@_layout}.tap do |layout| - unless layout.is_a?(String) || !layout - raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ - "should have returned a String, false, or nil" + begin + #{@_layout}.tap do |layout| + unless layout.is_a?(String) || !layout + raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ + "should have returned a String, false, or nil" + end end + rescue NameError => e + #{@_layout.inspect} end end ruby_eval @@ -342,12 +357,7 @@ module AbstractController # ==== Returns # Template:: The template object for the default layout (or nil) def _default_layout(require_layout = false) - begin - layout_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 + layout_name = _layout if action_has_layout? if require_layout && action_has_layout? && !layout_name raise ArgumentError, diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index f580ad4..392ae77 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -50,6 +50,15 @@ module AbstractControllerTests end end + class WithSymbolAsLayoutName < Base + layout :hello + + def index + render :template => ActionView::Template::Text.new("Hello string!") + end + end + + class WithStringChild < WithString end @@ -166,6 +175,12 @@ module AbstractControllerTests assert_equal "With String Hello string!", controller.response_body end + test "when layout is specified as a symbol, render with that layout" do + controller = WithSymbolAsLayoutName.new + controller.process(:index) + assert_equal "With String Hello string!", controller.response_body + end + test "when layout is overwriten by :default in render, render default layout" do controller = WithString.new controller.process(:overwrite_default) @@ -225,7 +240,7 @@ module AbstractControllerTests end test "when the layout is specified as a symbol and the method doesn't exist, raise an exception" do - assert_raises(NoMethodError) { WithSymbolAndNoMethod.new.process(:index) } + assert_raises( ActionView::MissingTemplate) { WithSymbolAndNoMethod.new.process(:index) } end test "when the layout is specified as a symbol and the method returns something besides a string/false/nil, raise an exception" do @@ -274,4 +289,4 @@ module AbstractControllerTests end end end -end \ No newline at end of file +end -- 1.6.5.2