aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2010-03-08 11:32:01 +0100
committerJosé Valim <jose.valim@gmail.com>2010-03-08 11:32:01 +0100
commit0a85380966e47a38292242e6c3b259d77c738ab5 (patch)
tree60945065b107368e6cd2f06b63cf40d16f6e88ac
parent34b2180451f842b180dd925bab10e8f4afa34490 (diff)
downloadrails-0a85380966e47a38292242e6c3b259d77c738ab5.tar.gz
rails-0a85380966e47a38292242e6c3b259d77c738ab5.tar.bz2
rails-0a85380966e47a38292242e6c3b259d77c738ab5.zip
Finally moved the find template logic to the views.
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb7
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb232
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb11
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb2
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb41
-rw-r--r--actionpack/lib/action_view/render/rendering.rb40
-rw-r--r--actionpack/lib/action_view/template/text.rb7
-rw-r--r--actionpack/test/abstract/abstract_controller_test.rb4
8 files changed, 152 insertions, 192 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index 648a2da795..6ac3806149 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -264,7 +264,7 @@ module AbstractController
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def _layout
- if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect})
+ if template_exists?("#{_implied_layout_name}", #{_prefix.inspect})
"#{_implied_layout_name}"
else
super
@@ -277,7 +277,9 @@ module AbstractController
end
end
- def render_to_body(options)
+ def _normalize_options(options)
+ super
+
if _include_layout?(options)
layout = options.key?(:layout) ? options[:layout] : :default
value = _layout_for_option(layout)
@@ -288,7 +290,6 @@ module AbstractController
# TODO Revisit this. :layout with :partial from controllers are not the same as in views
options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial)
end
- super
end
private
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 9093e90c97..d9087ce294 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -10,7 +10,7 @@ module AbstractController
end
end
- module Rendering
+ module ViewPaths
extend ActiveSupport::Concern
included do
@@ -21,21 +21,87 @@ module AbstractController
delegate :formats, :formats=, :to => :template_lookup
delegate :_view_paths, :to => :'self.class'
+ def template_lookup
+ @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup)
+ end
+
+ def details_for_lookup
+ { }
+ end
+
+ # The list of view paths for this controller. See ActionView::ViewPathSet for
+ # more details about writing custom view paths.
+ def view_paths
+ template_lookup.view_paths
+ end
+
+ def append_view_path(path)
+ template_lookup.view_paths.push(*path)
+ end
+
+ def prepend_view_path(path)
+ template_lookup.view_paths.unshift(*path)
+ end
+
+ protected
+
+ def template_exists?(*args)
+ template_lookup.exists?(*args)
+ end
+
+ def find_template(*args)
+ template_lookup.find(*args)
+ end
+
+ module ClassMethods
+ # Append a path to the list of view paths for this controller.
+ #
+ # ==== Parameters
+ # path<String, ViewPath>:: If a String is provided, it gets converted into
+ # the default view path. You may also provide a custom view path
+ # (see ActionView::ViewPathSet for more information)
+ def append_view_path(path)
+ self.view_paths = view_paths.dup + Array(path)
+ end
+
+ # Prepend a path to the list of view paths for this controller.
+ #
+ # ==== Parameters
+ # path<String, ViewPath>:: If a String is provided, it gets converted into
+ # the default view path. You may also provide a custom view path
+ # (see ActionView::ViewPathSet for more information)
+ def prepend_view_path(path)
+ self.view_paths = Array(path) + view_paths.dup
+ end
+
+ # A list of all of the default view paths for this controller.
+ def view_paths
+ _view_paths
+ end
+
+ # Set the view paths.
+ #
+ # ==== Parameters
+ # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that;
+ # otherwise, process the parameter into a ViewPathSet.
+ def view_paths=(paths)
+ self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths)
+ self._view_paths.freeze
+ end
+ end
+ end
+
+ module Rendering
+ extend ActiveSupport::Concern
+ include AbstractController::ViewPaths
+
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
- # View.for_controller[controller] Create a new ActionView instance for a
- # controller
- # View#render_partial[options]
- # - responsible for setting options[:_template]
- # - Returns String with the rendered partial
- # options<Hash>:: see _render_partial in ActionView::Base
- # View#render_template[template, layout, options, partial]
- # - Returns String with the rendered template
- # template<ActionView::Template>:: The template to render
- # layout<ActionView::Template>:: The layout to render around the template
- # options<Hash>:: See _render_template_with_layout in ActionView::Base
- # partial<Boolean>:: Whether or not the template to render is a partial
+ # View.for_controller[controller]
+ # Create a new ActionView instance for a controller
+ # View#render_template[options]
+ # Returns String with the rendered template
#
# Override this method in a module to change the default behavior.
def view_context
@@ -51,64 +117,23 @@ module AbstractController
end
# Raw rendering of a template to a Rack-compatible body.
- #
- # ==== Options
- # _partial_object<Object>:: The object that is being rendered. If this
- # exists, we are in the special case of rendering an object as a partial.
- #
# :api: plugin
def render_to_body(options = {})
- # TODO: Refactor so we can just use the normal template logic for this
- if options.key?(:partial)
- _render_partial(options)
- else
- _determine_template(options)
- _render_template(options)
- end
+ _process_options(options)
+ _render_template(options)
end
# Raw rendering of a template to a string. Just convert the results of
# render_to_body into a String.
- #
# :api: plugin
def render_to_string(options={})
_normalize_options(options)
AbstractController::Rendering.body_to_s(render_to_body(options))
end
- # Renders the template from an object.
- #
- # ==== Options
- # _template<ActionView::Template>:: The template to render
- # _layout<ActionView::Template>:: The layout to wrap the template in (optional)
+ # Find and renders a template based on the options given.
def _render_template(options)
- view_context.render_template(options)
- end
-
- # Renders the given partial.
- #
- # ==== Options
- # partial<String|Object>:: The partial name or the object to be rendered
- def _render_partial(options)
- view_context.render_partial(options)
- end
-
- def template_lookup
- @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render)
- end
-
- # The list of view paths for this controller. See ActionView::ViewPathSet for
- # more details about writing custom view paths.
- def view_paths
- template_lookup.view_paths
- end
-
- def append_view_path(path)
- template_lookup.view_paths.push(*path)
- end
-
- def prepend_view_path(path)
- template_lookup.view_paths.unshift(*path)
+ view_context.render_template(options) { |template| _with_template_hook(template) }
end
# The prefix used in render "foo" shortcuts.
@@ -134,59 +159,40 @@ module AbstractController
# and render "/foo" to render :file => "/foo".
def _normalize_args(action=nil, options={})
case action
+ when NilClass
when Hash
options, action = action, nil
when String, Symbol
action = action.to_s
case action.index("/")
when NilClass
- options[:_prefix] = _prefix
- options[:_template_name] = action
+ options[:action] = action
when 0
options[:file] = action
else
options[:template] = action
end
+ else
+ options.merge!(:partial => action)
end
options
end
def _normalize_options(options)
- end
+ if options[:partial] == true
+ options[:partial] = action_name
+ end
- # Take in a set of options and determine the template to render
- #
- # ==== Options
- # _template<ActionView::Template>:: If this is provided, the search is over
- # _template_name<#to_s>:: The name of the template to look up. Otherwise,
- # use the current action name.
- # _prefix<String>:: The prefix to look inside of. In a file system, this corresponds
- # to a directory.
- # _partial<TrueClass, FalseClass>:: Whether or not the file to look up is a partial
- def _determine_template(options)
- if options.key?(:text)
- options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text)
- elsif options.key?(:inline)
- handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb")
- template = ActionView::Template.new(options[:inline], "inline template", handler, {})
- options[:_template] = template
- elsif options.key?(:template)
- options[:_template_name] = options[:template]
- elsif options.key?(:file)
- options[:_template_name] = options[:file]
+ if (options.keys & [:partial, :file, :template]).empty?
+ options[:_prefix] ||= _prefix
end
- name = (options[:_template_name] || options[:action] || action_name).to_s
- options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty?
+
+ options[:template] ||= (options[:action] || action_name).to_s
details = _normalize_details(options)
template_lookup.details = details
-
- options[:_template] ||= find_template(name, options)
- end
-
- def details_for_render
- { }
+ options
end
def _normalize_details(options)
@@ -196,53 +202,11 @@ module AbstractController
details
end
- def find_template(name, options)
- template_lookup.find(name, options[:_prefix], options[:_partial])
- end
-
- def template_exists?(name, options)
- template_lookup.exists?(name, options[:_prefix], options[:_partial])
- end
-
- def format_for_text
- Mime[:text]
+ def _process_options(options)
end
- module ClassMethods
- # Append a path to the list of view paths for this controller.
- #
- # ==== Parameters
- # path<String, ViewPath>:: If a String is provided, it gets converted into
- # the default view path. You may also provide a custom view path
- # (see ActionView::ViewPathSet for more information)
- def append_view_path(path)
- self.view_paths = view_paths.dup + Array(path)
- end
-
- # Prepend a path to the list of view paths for this controller.
- #
- # ==== Parameters
- # path<String, ViewPath>:: If a String is provided, it gets converted into
- # the default view path. You may also provide a custom view path
- # (see ActionView::ViewPathSet for more information)
- def prepend_view_path(path)
- self.view_paths = Array(path) + view_paths.dup
- end
-
- # A list of all of the default view paths for this controller.
- def view_paths
- _view_paths
- end
-
- # Set the view paths.
- #
- # ==== Parameters
- # paths<ViewPathSet, Object>:: If a ViewPathSet is provided, use that;
- # otherwise, process the parameter into a ViewPathSet.
- def view_paths=(paths)
- self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths)
- self._view_paths.freeze
- end
+ def _with_template_hook(template)
+ self.formats = template.details[:formats]
end
end
end
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index 0cb20b2f0f..5cad0814ca 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -49,14 +49,19 @@ module ActionController
super
end
- def render_to_body(options)
- if options.is_a?(Hash) && options.key?(:template)
- options[:template].sub!(/^\//, '')
+ def _normalize_options(options)
+ # TODO Deprecate this. Rails 2.x allowed to give a template as action.
+ if options[:action] && options[:action].to_s.include?(?/)
+ options[:template] = options.delete(:action)
end
options[:text] = nil if options.delete(:nothing) == true
options[:text] = " " if options.key?(:text) && options[:text].nil?
+ super
+ end
+ def render_to_body(options)
+ options[:template].sub!(/^\//, '') if options.key?(:template)
super || " "
end
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index c3e3b8fdf5..282dcf66b3 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -12,7 +12,7 @@ module ActionController
def method_for_action(action_name)
super || begin
- if template_exists?(action_name.to_s, :_prefix => controller_path)
+ if template_exists?(action_name.to_s, _prefix)
"default_render"
end
end
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index 60d61999de..f892bd9b91 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -6,46 +6,20 @@ module ActionController
include AbstractController::Rendering
def process(*)
- self.formats = request.formats.map {|x| x.to_sym }
+ self.formats = request.formats.map { |x| x.to_sym }
super
end
def render(*args)
raise ::AbstractController::DoubleRenderError if response_body
- args << {} unless args.last.is_a?(Hash)
- super(*args)
- self.content_type ||= args.last[:_template].mime_type.to_s
- response_body
- end
-
- def render_to_body(options)
- _process_options(options)
super
+ response_body
end
private
- def _render_partial(options)
- options[:partial] = action_name if options[:partial] == true
- options[:_details] = details_for_render
- super
- end
-
- def format_for_text
- formats.first
- end
-
def _normalize_args(action=nil, options={}, &blk)
- case action
- when NilClass
- when Hash
- options = super(action.delete(:action), action)
- when String, Symbol
- options = super
- else
- options.merge!(:partial => action)
- end
-
+ options = super
options[:update] = blk if block_given?
options
end
@@ -64,9 +38,18 @@ module ActionController
def _process_options(options)
status, content_type, location = options.values_at(:status, :content_type, :location)
+
self.status = status if status
self.content_type = content_type if content_type
self.headers["Location"] = url_for(location) if location
+
+ super
end
+
+ def _with_template_hook(template)
+ super
+ self.content_type ||= template.mime_type.to_s
+ end
+
end
end
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index 17fb110eb4..c6d95e88e2 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -24,18 +24,8 @@ module ActionView
return _render_partial(options)
end
- template = if options[:file]
- find(options[:file])
- elsif options[:inline]
- handler = Template.handler_class_for_extension(options[:type] || "erb")
- Template.new(options[:inline], "inline template", handler, {})
- elsif options[:text]
- Template::Text.new(options[:text])
- end
-
- if template
- _render_template(template, layout, :locals => options[:locals])
- end
+ template = _determine_template(options)
+ _render_template(template, layout, :locals => options[:locals]) if template
when :update
update_page(&block)
else
@@ -87,8 +77,28 @@ module ActionView
# _layout:: The layout, if any, to wrap the Template in
def render_template(options)
_evaluate_assigns_and_ivars
- template, layout = options.values_at(:_template, :layout)
- _render_template(template, layout, options)
+ if options.key?(:partial)
+ _render_partial(options)
+ else
+ template = _determine_template(options)
+ yield template if block_given?
+ _render_template(template, options[:layout], options)
+ end
+ end
+
+ def _determine_template(options)
+ if options.key?(:inline)
+ handler = Template.handler_class_for_extension(options[:type] || "erb")
+ Template.new(options[:inline], "inline template", handler, {})
+ elsif options.key?(:text)
+ Template::Text.new(options[:text], self.formats.try(:first))
+ elsif options.key?(:_template)
+ options[:_template]
+ elsif options.key?(:file)
+ find(options[:file], options[:_prefix])
+ elsif options.key?(:template)
+ find(options[:template], options[:_prefix])
+ end
end
def _find_layout(layout)
@@ -102,8 +112,6 @@ module ActionView
end
def _render_template(template, layout = nil, options = {})
- self.formats = template.details[:formats]
-
locals = options[:locals] || {}
layout = _find_layout(layout) if layout
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index 2abb352d4e..5978a8a3ac 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -1,11 +1,10 @@
module ActionView #:nodoc:
class Template
class Text < String #:nodoc:
- HTML = Mime[:html]
-
- def initialize(string, content_type = HTML)
+ def initialize(string, content_type = nil)
super(string.to_s)
- @content_type = Mime[content_type] || content_type
+ @content_type = Mime[content_type] || content_type if content_type
+ @content_type ||= Mime::TEXT
end
def details
diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb
index 4ad87d9762..f70d497481 100644
--- a/actionpack/test/abstract/abstract_controller_test.rb
+++ b/actionpack/test/abstract/abstract_controller_test.rb
@@ -59,11 +59,11 @@ module AbstractController
end
def rendering_to_body
- self.response_body = render_to_body :_template_name => "naked_render.erb"
+ self.response_body = render_to_body :template => "naked_render.erb"
end
def rendering_to_string
- self.response_body = render_to_string :_template_name => "naked_render.erb"
+ self.response_body = render_to_string :template => "naked_render.erb"
end
end