class ActionView::Partials::PartialRenderer
def collection
def collection if @object.respond_to?(:to_ary) @object elsif @options.key?(:collection) @options[:collection] || [] end end
def collection_with_template(template = @template)
def collection_with_template(template = @template) segments, locals, template = [], @locals, @template if @options[:as] as = @options[:as] counter = "#{as}_counter".to_sym else as = template.variable_name counter = template.counter_name end locals[counter] = -1 @collection.each do |object| locals[counter] += 1 locals[as] = object segments << template.render(@view, locals) end segments end
def collection_without_template(collection_paths = @collection_paths)
def collection_without_template(collection_paths = @collection_paths) segments, locals = [], @locals index, template = -1, nil if @options[:as] as = @options[:as] counter = "#{as}_counter" end @collection.each_with_index do |object, i| template = find_template(collection_paths[i]) locals[as || template.variable_name] = object locals[counter || template.counter_name] = (index += 1) segments << template.render(@view, locals) end @template = template segments end
def find_template(path=@path)
def find_template(path=@path) return path unless path.is_a?(String) prefix = @view.controller_path unless path.include?(?/) @view.find_template(path, prefix, true) end
def initialize(view_context, options, block)
def initialize(view_context, options, block) @view = view_context @partial_names = PARTIAL_NAMES[@view.controller.class.name] setup(options, block) end
def partial_path(object = @object)
def partial_path(object = @object) @partial_names[object.class.name] ||= begin object = object.to_model if object.respond_to?(:to_model) object.class.model_name.partial_path.dup.tap do |partial| path = @view.controller_path partial.insert(0, "#{File.dirname(path)}/") if partial.include?(?/) && path.include?(?/) end end end
def render
def render identifier = ((@template = find_template) ? @template.identifier : @path) if @collection ActiveSupport::Notifications.instrument("render_collection.action_view", :identifier => identifier || "collection", :count => @collection.size) do render_collection end else content = ActiveSupport::Notifications.instrument("render_partial.action_view", :identifier => identifier) do render_partial end if !@block && (layout = @options[:layout]) content = @view._render_layout(find_template(layout), @locals){ content } end content end end
def render_collection
def render_collection return nil if @collection.blank? if @options.key?(:spacer_template) spacer = find_template(@options[:spacer_template]).render(@view, @locals) end result = @template ? collection_with_template : collection_without_template result.join(spacer).html_safe end
def render_partial(object = @object)
def render_partial(object = @object) locals, view, template = @locals, @view, @template object ||= locals[template.variable_name] locals[@options[:as] || template.variable_name] = object template.render(view, locals) do |*name| view._layout_for(*name, &@block) end end
def setup(options, block)
def setup(options, block) partial = options[:partial] @options = options @locals = options[:locals] || {} @block = block if String === partial @object = options[:object] @path = partial @collection = collection else @object = partial if @collection = collection paths = @collection_paths = @collection.map { |o| partial_path(o) } @path = paths.uniq.size == 1 ? paths.first : nil else @path = partial_path end end end