From 890321e51e0c51f61f9198d247727e98f7485899 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Thu, 19 Mar 2009 15:45:48 -0700 Subject: [PATCH] Get very basic layouts working. * Required small architecture change --- .../lib/action_controller/abstract/layouts.rb | 7 +-- .../action_controller/abstract/renderer.rb | 47 +++++++++++++------ actionpack/lib/action_controller/new_base.rb | 1 + .../lib/action_controller/new_base/layouts.rb | 19 ++++++++ .../action_controller/new_base/renderer.rb | 16 ++++--- .../abstract_controller_test.rb | 16 ++++++- .../test/new_base/render_action_test.rb | 23 +++++++++ actionpack/test/new_base/test_helper.rb | 1 + .../hello_world.html.erb | 1 + .../with_layout/layouts/application.html.erb | 1 + 10 files changed, 104 insertions(+), 28 deletions(-) create mode 100644 actionpack/lib/action_controller/new_base/layouts.rb create mode 100644 actionpack/test/new_base/views/with_layout/happy_path/render_action_with_layout/hello_world.html.erb create mode 100644 actionpack/test/new_base/views/with_layout/layouts/application.html.erb diff --git a/actionpack/lib/action_controller/abstract/layouts.rb b/actionpack/lib/action_controller/abstract/layouts.rb index c8d6e77fce..c6b99a6d45 100644 --- a/actionpack/lib/action_controller/abstract/layouts.rb +++ b/actionpack/lib/action_controller/abstract/layouts.rb @@ -1,10 +1,7 @@ module AbstractController module Layouts - def _render_template(tmp) - _action_view._render_template_with_layout(tmp, _layout) - end - - def _layout + def _render_template(template, options) + _action_view._render_template_with_layout(template, options[:_layout]) end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index 19a64b0c38..ad996d0daf 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -4,12 +4,14 @@ module AbstractController module Renderer def self.included(klass) - klass.class_eval do + klass.class_eval do extend ClassMethods + attr_internal :formats - - extlib_inheritable_accessor :view_paths - self.view_paths ||= ActionView::PathSet.new + + extlib_inheritable_accessor :_view_paths + + self._view_paths ||= ActionView::PathSet.new include AbstractController::Logger end end @@ -17,27 +19,42 @@ def self.included(klass) def _action_view @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) end - - def _prefix + + def render(name = action_name, options = {}) + self.response_body = render_to_string(name, options) end - def render(template = action_name) - self.response_body = render_to_string(template) - end - - def render_to_string(template = action_name, prefix = true) - tmp = view_paths.find_by_parts(template.to_s, formats, (_prefix if prefix)) - _render_template(tmp) + # Raw rendering of a template. + # ==== + # @option _prefix The template's path prefix + # @option _layout The relative path to the layout template to use + # + # :api: plugin + def render_to_string(name = action_name, options = {}) + template = view_paths.find_by_parts(name.to_s, formats, options[:_prefix]) + _render_template(template, options) end - def _render_template(tmp) - _action_view._render_template_with_layout(tmp) + def _render_template(template, options) + _action_view._render_template_with_layout(template) end + + def view_paths() _view_paths end module ClassMethods + def append_view_path(path) self.view_paths << path end + + def view_paths + self._view_paths + end + + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? + paths : ActionView::Base.process_view_paths(paths) + end end end end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base.rb b/actionpack/lib/action_controller/new_base.rb index 2870f71b7d..7c65f1cdc1 100644 --- a/actionpack/lib/action_controller/new_base.rb +++ b/actionpack/lib/action_controller/new_base.rb @@ -1,6 +1,7 @@ module ActionController autoload :AbstractBase, "action_controller/new_base/base" autoload :HideActions, "action_controller/new_base/hide_actions" + autoload :Layouts, "action_controller/new_base/layouts" autoload :Renderer, "action_controller/new_base/renderer" autoload :UrlFor, "action_controller/new_base/url_for" end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/layouts.rb b/actionpack/lib/action_controller/new_base/layouts.rb new file mode 100644 index 0000000000..cdf2224e39 --- /dev/null +++ b/actionpack/lib/action_controller/new_base/layouts.rb @@ -0,0 +1,19 @@ +module ActionController + module Layouts + def render_to_string(options) + options[:_layout] = options[:layout] || _layout + super + end + + def _layout + begin + view_paths.find_by_parts(controller_path, formats, "layouts") + rescue ActionView::MissingTemplate + begin + view_paths.find_by_parts("application", formats, "layouts") + rescue ActionView::MissingTemplate + end + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/new_base/renderer.rb b/actionpack/lib/action_controller/new_base/renderer.rb index 540924936d..1308537160 100644 --- a/actionpack/lib/action_controller/new_base/renderer.rb +++ b/actionpack/lib/action_controller/new_base/renderer.rb @@ -11,6 +11,11 @@ module Renderer # end # end + def initialize(*) + self.formats = [:html] + super + end + def render(action, options = {}) # TODO: Move this into #render_to_string if action.is_a?(Hash) @@ -23,22 +28,21 @@ def render(action, options = {}) self.response_body = render_to_string(options) end - - def render_to_string(options) - self.formats = [:html] + def render_to_string(options) unless options.is_a?(Hash) options = {:action => options} end - + if options.key?(:text) _render_text(options) elsif options.key?(:template) template = options.delete(:template) - super(template, false) + super(template) elsif options.key?(:action) template = options.delete(:action).to_s - super(template) + options[:_prefix] = _prefix + super(template, options) end end diff --git a/actionpack/test/abstract_controller/abstract_controller_test.rb b/actionpack/test/abstract_controller/abstract_controller_test.rb index 22fc1a8c41..31c28a5c48 100644 --- a/actionpack/test/abstract_controller/abstract_controller_test.rb +++ b/actionpack/test/abstract_controller/abstract_controller_test.rb @@ -28,7 +28,14 @@ class TestBasic < ActiveSupport::TestCase # ==== class RenderingController < AbstractController::Base include Renderer - + + def _prefix() end + + def render(name = action_name, options = {}) + options[:_prefix] = _prefix + super + end + append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views")) end @@ -121,7 +128,12 @@ def self.layout(formats) def _layout self.class.layout(formats) - end + end + + def render_to_string(name = action_name, options = {}) + options[:_layout] = options[:layout] || _layout + super + end end class Me4 < WithLayouts diff --git a/actionpack/test/new_base/render_action_test.rb b/actionpack/test/new_base/render_action_test.rb index b6e98f82aa..99482cd4a1 100644 --- a/actionpack/test/new_base/render_action_test.rb +++ b/actionpack/test/new_base/render_action_test.rb @@ -2,6 +2,7 @@ module HappyPath + # This has no layout and it works class RenderActionController < ActionController::Base2 def render_action_hello_world @@ -71,5 +72,27 @@ class TestRenderActionWithSymbol < SimpleRouteCase assert_body "Hello world!" assert_status 200 end + + # # ==== Render actions with layouts ==== + + class RenderActionWithLayoutController < ActionController::Base2 + # Set the view path to an application view structure with layouts + self.view_paths = [File.join(File.dirname(__FILE__), 'views', 'with_layout')] + + def hello_world + render :action => "hello_world" + end + end + + class TestRenderActionWithLayout < SimpleRouteCase + describe %( + Render hello_world and implicitly use application.html.erb as a layout if + no layout is specified and no controller layout is present + ) + + get "/happy_path/render_action_with_layout/hello_world" + assert_body "OHAI Hello World! KTHXBAI" + assert_status 200 + end end \ No newline at end of file diff --git a/actionpack/test/new_base/test_helper.rb b/actionpack/test/new_base/test_helper.rb index 7a1adc3755..af790aa5dd 100644 --- a/actionpack/test/new_base/test_helper.rb +++ b/actionpack/test/new_base/test_helper.rb @@ -33,6 +33,7 @@ class Base2 < AbstractBase include ActionController::HideActions include ActionController::UrlFor include ActionController::Renderer + include ActionController::Layouts def self.inherited(klass) @subclasses ||= [] diff --git a/actionpack/test/new_base/views/with_layout/happy_path/render_action_with_layout/hello_world.html.erb b/actionpack/test/new_base/views/with_layout/happy_path/render_action_with_layout/hello_world.html.erb new file mode 100644 index 0000000000..c57eff55eb --- /dev/null +++ b/actionpack/test/new_base/views/with_layout/happy_path/render_action_with_layout/hello_world.html.erb @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/actionpack/test/new_base/views/with_layout/layouts/application.html.erb b/actionpack/test/new_base/views/with_layout/layouts/application.html.erb new file mode 100644 index 0000000000..25f839fded --- /dev/null +++ b/actionpack/test/new_base/views/with_layout/layouts/application.html.erb @@ -0,0 +1 @@ +OHAI <%= yield %> KTHXBAI \ No newline at end of file