From 3cecbc21e37f772a72917f80c53a7645f81d94c5 Mon Sep 17 00:00:00 2001 From: Yehuda Katz and Carl Lerche Date: Tue, 7 Apr 2009 17:57:20 -0700 Subject: Get Base2 layouts to work :) --- .../lib/action_controller/abstract/layouts.rb | 34 +++++++++------- .../lib/action_controller/new_base/layouts.rb | 23 +++++++++++ .../test/abstract_controller/layouts_test.rb | 13 ++++++- actionpack/test/new_base/render_action_test.rb | 12 +++--- actionpack/test/new_base/render_layout_test.rb | 45 ++++++++++++++++++++++ actionpack/test/new_base/render_template_test.rb | 4 +- actionpack/test/new_base/test_helper.rb | 12 ++++++ 7 files changed, 121 insertions(+), 22 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index 1990941916..478b301a26 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -17,6 +17,16 @@ module AbstractController name.underscore end + # Takes the specified layout and creates a _layout method to be called + # by _default_layout + # + # If the specified layout is a: + # String:: return the string + # Symbol:: call the method specified by the symbol + # false:: return nil + # none:: If a layout is found in the view paths with the controller's + # name, return that string. Otherwise, use the superclass' + # layout (which might also be implied) def _write_layout_method case @_layout when String @@ -46,25 +56,23 @@ module AbstractController private def _layout() end # This will be overwritten - - def _layout_for_option(name) - case name - when String then _layout_for_name(name) - when true then _default_layout(true) - when false, nil then nil - else - raise ArgumentError, - "String, true, or false, expected for `layout'; you passed #{name.inspect}" - end - end def _layout_for_name(name) - view_paths.find_by_parts(name, formats, "layouts") + unless [String, FalseClass, NilClass].include?(name.class) + raise ArgumentError, "String, false, or nil expected; you passed #{name.inspect}" + end + + name && view_paths.find_by_parts(name, formats, "layouts") end def _default_layout(require_layout = false) + if require_layout && !_layout + raise ArgumentError, + "There was no default layout for #{self.class} in #{view_paths.inspect}" + end + begin - _layout_for_option(_layout) + layout = _layout_for_name(_layout) rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb index 2351472dad..149847c968 100644 --- a/actionpack/lib/action_controller/new_base/layouts.rb +++ b/actionpack/lib/action_controller/new_base/layouts.rb @@ -3,12 +3,35 @@ module ActionController depends_on ActionController::Renderer depends_on AbstractController::Layouts + module ClassMethods + def _implied_layout_name + controller_path + end + end + def render_to_string(options) + # render :text => ..., :layout => ... + # or + # render :anything_else if !options.key?(:text) || options.key?(:layout) options[:_layout] = options.key?(:layout) ? _layout_for_option(options[:layout]) : _default_layout end super end + + private + + def _layout_for_option(name) + case name + when String then _layout_for_name(name) + when true then _default_layout(true) + when false, nil then nil + else + raise ArgumentError, + "String, true, or false, expected for `layout'; you passed #{name.inspect}" + end + end + end end \ No newline at end of file diff --git a/actionpack/test/abstract_controller/layouts_test.rb b/actionpack/test/abstract_controller/layouts_test.rb index 541d126958..5dd68ec28e 100644 --- a/actionpack/test/abstract_controller/layouts_test.rb +++ b/actionpack/test/abstract_controller/layouts_test.rb @@ -144,7 +144,6 @@ module AbstractControllerTests AbstractController::Base.subclasses.each do |klass| klass = klass.constantize next unless klass < AbstractController::Layouts - p klass klass.class_eval do _write_layout_method end @@ -217,7 +216,17 @@ module AbstractControllerTests "parent has specified a layout, use the child controller layout" do result = WithChildOfImplied.process(:index) assert_equal "With Implied Hello string!", result.response_obj[:body] - end + end + + test "raises an exception when specifying layout true" do + assert_raises ArgumentError do + Object.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + class ::BadOmgFailLolLayout < AbstractControllerTests::Layouts::Base + layout true + end + RUBY_EVAL + end + end end end end \ No newline at end of file diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index bbc8939af4..2bfb374a31 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -91,7 +91,9 @@ module RenderAction describe "rendering a normal template with full path with layout => true" test "raises an exception when requesting a layout and none exist" do - assert_raise(ActionView::MissingTemplate) { get "/render_action/basic/hello_world_with_layout" } + assert_raise(ArgumentError, /no default layout for RenderAction::BasicController in/) do + get "/render_action/basic/hello_world_with_layout" + end end end @@ -124,13 +126,13 @@ end module RenderActionWithApplicationLayout # # ==== Render actions with layouts ==== - - class BasicController < ActionController::Base2 + + class BasicController < ::ApplicationController # Set the view path to an application view structure with layouts self.view_paths = self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( "render_action_with_application_layout/basic/hello_world.html.erb" => "Hello World!", - "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", - "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai" + "layouts/application.html.erb" => "OHAI <%= yield %> KTHXBAI", + "layouts/greetings.html.erb" => "Greetings <%= yield %> Bai" )] def hello_world diff --git a/actionpack/test/new_base/render_layout_test.rb b/actionpack/test/new_base/render_layout_test.rb index e69de29bb2..facf67ea85 100644 --- a/actionpack/test/new_base/render_layout_test.rb +++ b/actionpack/test/new_base/render_layout_test.rb @@ -0,0 +1,45 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") + +module ControllerLayouts + class ImplicitController < ::ApplicationController + + self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + "layouts/application.html.erb" => "OMG <%= yield %> KTHXBAI", + "basic.html.erb" => "Hello world!" + )] + + def index + render :template => "basic" + end + end + + class TestImplicitLayout < SimpleRouteCase + describe "rendering a normal template, but using the implicit layout" + + get "/controller_layouts/implicit/index" + assert_body "OMG Hello world! KTHXBAI" + assert_status 200 + end + + class ImplicitNameController < ::ApplicationController + + self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( + "layouts/controller_layouts/implicit_name.html.erb" => "OMGIMPLICIT <%= yield %> KTHXBAI", + "basic.html.erb" => "Hello world!" + )] + + def index + render :template => "basic" + end + end + + class TestImplicitNamedLayout < SimpleRouteCase + describe "rendering a normal template, but using an implicit NAMED layout" + + get "/controller_layouts/implicit_name/index" + assert_body "OMGIMPLICIT Hello world! KTHXBAI" + assert_status 200 + end + + +end \ No newline at end of file diff --git a/actionpack/test/new_base/render_template_test.rb b/actionpack/test/new_base/render_template_test.rb index 273e26b83f..c6c0269b40 100644 --- a/actionpack/test/new_base/render_template_test.rb +++ b/actionpack/test/new_base/render_template_test.rb @@ -57,8 +57,8 @@ module HappyPath assert_body "Elastica" assert_status 200 end - - class RenderTemplateWithLayoutController < ActionController::Base2 + + class RenderTemplateWithLayoutController < ::ApplicationController self.view_paths = [ActionView::FixtureTemplate::FixturePath.new( "test/basic.html.erb" => "Hello from basic.html.erb", diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 5edd7b4f63..d29449ddc1 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -69,6 +69,15 @@ class Rack::TestCase < ActiveSupport::TestCase end ActionController::Routing.use_controllers!(controllers) + + # Move into a bootloader + AbstractController::Base.subclasses.each do |klass| + klass = klass.constantize + next unless klass < AbstractController::Layouts + klass.class_eval do + _write_layout_method + end + end end def app @@ -123,6 +132,9 @@ class Rack::TestCase < ActiveSupport::TestCase end +class ::ApplicationController < ActionController::Base2 +end + class SimpleRouteCase < Rack::TestCase setup do ActionController::Routing::Routes.draw do |map| -- cgit v1.2.3