diff options
Diffstat (limited to 'actionpack/lib/action_controller/abstract/renderer.rb')
-rw-r--r-- | actionpack/lib/action_controller/abstract/renderer.rb | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/actionpack/lib/action_controller/abstract/renderer.rb b/actionpack/lib/action_controller/abstract/renderer.rb index b5c31a27ee..b58688c9da 100644 --- a/actionpack/lib/action_controller/abstract/renderer.rb +++ b/actionpack/lib/action_controller/abstract/renderer.rb @@ -1,6 +1,15 @@ require "action_controller/abstract/logger" module AbstractController + class AbstractControllerError < StandardError; end + class DoubleRenderError < AbstractControllerError + DEFAULT_MESSAGE = "Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like \"redirect_to(...) and return\"." + + def initialize(message = nil) + super(message || DEFAULT_MESSAGE) + end + end + module Renderer extend ActiveSupport::DependencyModule @@ -15,31 +24,36 @@ module AbstractController end def _action_view - @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) + @_action_view ||= ActionView::Base.new(self.class.view_paths, {}, self) end - + def render(options = {}) + if response_body + raise AbstractController::DoubleRenderError, "OMG" + end + self.response_body = render_to_body(options) end - + # Raw rendering of a template to a Rack-compatible body. # ==== # @option _prefix<String> The template's path prefix # @option _layout<String> The relative path to the layout template to use - # + # # :api: plugin def render_to_body(options = {}) name = options[:_template_name] || action_name - - template = options[:_template] || view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) - _render_template(template, options) + + options[:_template] ||= view_paths.find_by_parts(name.to_s, {:formats => formats}, options[:_prefix]) + + _render_template(options[:_template], options) end # Raw rendering of a template to a string. # ==== # @option _prefix<String> The template's path prefix # @option _layout<String> The relative path to the layout template to use - # + # # :api: plugin def render_to_string(options = {}) AbstractController::Renderer.body_to_s(render_to_body(options)) @@ -48,7 +62,7 @@ module AbstractController def _render_template(template, options) _action_view._render_template_with_layout(template) end - + def view_paths() _view_paths end # Return a string representation of a Rack-compatible response body. @@ -64,14 +78,15 @@ module AbstractController 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) |