diff options
author | Yehuda Katz <wycats@gmail.com> | 2009-08-08 12:26:58 -0300 |
---|---|---|
committer | Yehuda Katz <wycats@gmail.com> | 2009-08-08 12:44:26 -0300 |
commit | d0301e13f4d6e2ddf956ecf80e85384c1ea5346c (patch) | |
tree | 3123d73744b834834579bf1996e0c286952c110c /actionpack/lib/action_view/render/partials.rb | |
parent | a8645593a4446a89b2e699e153adca968340581a (diff) | |
download | rails-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/lib/action_view/render/partials.rb')
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb | 142 |
1 files changed, 82 insertions, 60 deletions
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 |