aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorYehuda Katz <wycats@gmail.com>2009-08-08 12:26:58 -0300
committerYehuda Katz <wycats@gmail.com>2009-08-08 12:44:26 -0300
commitd0301e13f4d6e2ddf956ecf80e85384c1ea5346c (patch)
tree3123d73744b834834579bf1996e0c286952c110c /actionpack
parenta8645593a4446a89b2e699e153adca968340581a (diff)
downloadrails-d0301e13f4d6e2ddf956ecf80e85384c1ea5346c.tar.gz
rails-d0301e13f4d6e2ddf956ecf80e85384c1ea5346c.tar.bz2
rails-d0301e13f4d6e2ddf956ecf80e85384c1ea5346c.zip
First pass at making partial rendering an Object. More cleanup to come.
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb18
-rw-r--r--actionpack/lib/action_controller/metal/rendering_controller.rb3
-rw-r--r--actionpack/lib/action_view/render/partials.rb142
-rw-r--r--actionpack/lib/action_view/render/rendering.rb3
4 files changed, 93 insertions, 73 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb
index c1fb80415b..0063d54149 100644
--- a/actionpack/lib/abstract_controller/layouts.rb
+++ b/actionpack/lib/abstract_controller/layouts.rb
@@ -89,16 +89,18 @@ module AbstractController
end
def render_to_body(options = {})
+ # In the case of a partial with a layout, handle the layout
+ # here, and make sure the view does not try to handle it
+ layout = options.delete(:layout) if options.key?(:partial)
+
response = super
- if options.key?(:partial)
- # This is a little bit messy. We need to explicitly handle partial
- # layouts here since the core lookup logic is in the view, but
- # we need to determine the layout based on the controller
- if options.key?(:layout)
- layout = _layout_for_option(options[:layout], options[:_template].details)
- response = layout.render(view_context, options[:locals]) { response }
- end
+ # This is a little bit messy. We need to explicitly handle partial
+ # layouts here since the core lookup logic is in the view, but
+ # we need to determine the layout based on the controller
+ if layout
+ layout = _layout_for_option(layout, options[:_template].details)
+ response = layout.render(view_context, options[:locals] || {}) { response }
end
response
diff --git a/actionpack/lib/action_controller/metal/rendering_controller.rb b/actionpack/lib/action_controller/metal/rendering_controller.rb
index c8922290f3..5b1be763ad 100644
--- a/actionpack/lib/action_controller/metal/rendering_controller.rb
+++ b/actionpack/lib/action_controller/metal/rendering_controller.rb
@@ -53,9 +53,6 @@ module ActionController
super
end
- def _render_partial(partial, options)
- end
-
def _process_options(options)
status, content_type, location = options.values_at(:status, :content_type, :location)
self.status = status if status
diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb
index c559a572b0..986d3af454 100644
--- a/actionpack/lib/action_view/render/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -170,95 +170,117 @@ module ActionView
# <%- end -%>
# <% end %>
module Partials
- extend ActiveSupport::Memoizable
extend ActiveSupport::Concern
- included do
- attr_accessor :_partial
- end
-
- module ClassMethods
- def _partial_names
- @_partial_names ||= ActiveSupport::ConcurrentHash.new
+ class PartialRenderer
+ def self.partial_names
+ @partial_names ||= Hash.new {|h,k| h[k] = ActiveSupport::ConcurrentHash.new }
end
- end
- def render_partial(options)
- @assigns_added = false
- # TODO: Handle other details here.
- self.formats = options[:_details][:formats]
- _render_partial(options)
- end
+ def initialize(view_context, options, formats)
+ object = options[:partial]
- def _render_partial(options, &block) #:nodoc:
- options[:locals] ||= {}
+ @view, @formats = view_context, formats
+ @options = options || {}
- path = partial = options[:partial]
+ if object.is_a?(String)
+ @path = object
+ elsif
+ @object = object
+ @path = partial_path unless collection
+ end
- if partial.respond_to?(:to_ary)
- return _render_partial_collection(partial, options, &block)
- elsif !partial.is_a?(String)
- options[:object] = object = partial
- path = _partial_path(object)
+ @locals = options[:locals] || {}
+ @object ||= @options[:object] || @locals[:object]
+ @layout = options[:layout]
end
- _render_partial_object(_pick_partial_template(path), options, &block)
- end
+ def render(&block)
+ template = find if @path
- private
- def _partial_path(object)
- self.class._partial_names[[controller.class, object.class]] ||= begin
- name = object.class.model_name
- if controller_path && controller_path.include?("/")
- File.join(File.dirname(controller_path), name.partial_path)
- else
- name.partial_path
- end
+ if collection
+ render_collection(template, &block)
+ else
+ render_object(template, &block)
end
end
- def _render_partial_template(template, locals, object, options = {}, &block)
- options[:_template] = template
- locals[:object] = locals[template.variable_name] = object
- locals[options[:as]] = object if options[:as]
+ def render_template(template, &block)
+ @options[:_template] = template
+ @locals[:object] = @locals[template.variable_name] = @object
+ @locals[@options[:as]] = @object if @options[:as]
- _render_single_template(template, locals, &block)
+ content = @view._render_single_template(template, @locals, &block)
+ return content if block_given? || !@layout
+ find(@layout).render(@view, @locals) { content }
end
- def _render_partial_object(template, options, &block)
- if options.key?(:collection)
- _render_partial_collection(options.delete(:collection), options, template, &block)
- else
- locals = (options[:locals] ||= {})
- object = options[:object] || locals[:object] || locals[template.variable_name]
-
- _render_partial_template(template, locals, object, options, &block)
- end
+ def render_object(template, &block)
+ @object ||= @locals[template.variable_name]
+ render_template(template, &block)
end
- def _render_partial_collection(collection, options = {}, template = nil, &block) #:nodoc:
- options[:_template] ||= template
+ def render_collection(passed_template = nil, &block)
+ @options[:_template] = passed_template
return nil if collection.blank?
- if options.key?(:spacer_template)
- spacer = _render_partial(:partial => options[:spacer_template])
+ if @options.key?(:spacer_template)
+ spacer = @view.render_partial(
+ :partial => @options[:spacer_template], :_details => @options[:_details])
end
- locals, index = options[:locals] || {}, 0
+ index = 0
- collection.map do |object|
- tmp = template || _pick_partial_template(_partial_path(object))
- locals[tmp.counter_name] = index
+ collection.map do |@object|
+ @path = partial_path
+ template = passed_template || find
+ @locals[template.counter_name] = index
index += 1
- _render_partial_template(tmp, locals, object, options, &block)
+ render_template(template, &block)
end.join(spacer)
end
- def _pick_partial_template(partial_path) #:nodoc:
- prefix = controller_path unless partial_path.include?(?/)
- find(partial_path, {:formats => formats}, prefix, true)
+ private
+ def collection
+ @collection ||= if @object.respond_to?(:to_ary)
+ @object
+ elsif @options.key?(:collection)
+ @options[:collection] || []
+ end
end
+
+ def find(path = @path)
+ prefix = @view.controller.controller_path unless path.include?(?/)
+ @view.find(path, {:formats => @view.formats}, prefix, true)
+ end
+
+ def partial_path(object = @object)
+ self.class.partial_names[@view.controller.class][object.class] ||= begin
+ return nil unless object.class.respond_to?(:model_name)
+
+ name = object.class.model_name
+ path = @view.controller_path
+ if path && path.include?(?/)
+ File.join(File.dirname(path), name.partial_path)
+ else
+ name.partial_path
+ end
+ end
+ end
+ end
+
+ def render_partial(options)
+ @assigns_added = false
+ # TODO: Handle other details here.
+ self.formats = options[:_details][:formats] if options[:_details]
+ _render_partial(options)
+ end
+
+ def _render_partial(options, &block) #:nodoc:
+ PartialRenderer.new(self, options, formats).render(&block)
+ end
+
end
end
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
index 742b965556..c7afc56e3b 100644
--- a/actionpack/lib/action_view/render/rendering.rb
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -20,8 +20,7 @@ module ActionView
if block_given?
return concat(_render_partial(options.merge(:partial => layout), &block))
elsif options.key?(:partial)
- layout = _pick_partial_template(layout) if layout
- return _render_content(_render_partial(options), layout, options[:locals])
+ return _render_partial(options)
end
layout = find(layout, {:formats => formats}) if layout