Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve and cleanup a bit partial renderer #6293

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions actionpack/lib/action_view/renderer/abstract_renderer.rb
Expand Up @@ -14,12 +14,10 @@ def render
protected protected


def extract_details(options) def extract_details(options)
details = {} @lookup_context.registered_details.each_with_object({}) do |key, details|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer the old way in this case, but just personal preference. :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D I think I like each_with_object

@lookup_context.registered_details.each do |key|
next unless value = options[key] next unless value = options[key]
details[key] = Array(value) details[key] = Array(value)
end end
details
end end


def instrument(name, options={}) def instrument(name, options={})
Expand Down
71 changes: 36 additions & 35 deletions actionpack/lib/action_view/renderer/partial_renderer.rb
Expand Up @@ -283,19 +283,19 @@ def render_collection
return nil if @collection.blank? return nil if @collection.blank?


if @options.key?(:spacer_template) if @options.key?(:spacer_template)
spacer = find_template(@options[:spacer_template]).render(@view, @locals) spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
end end


result = @template ? collection_with_template : collection_without_template result = @template ? collection_with_template : collection_without_template
result.join(spacer).html_safe result.join(spacer).html_safe
end end


def render_partial def render_partial
locals, view, block = @locals, @view, @block view, locals, block = @view, @locals, @block
object, as = @object, @variable object, as = @object, @variable


if !block && (layout = @options[:layout]) if !block && (layout = @options[:layout])
layout = find_template(layout, @locals.keys + [@variable]) layout = find_template(layout, @template_keys)
end end


object ||= locals[as] object ||= locals[as]
Expand Down Expand Up @@ -337,6 +337,7 @@ def setup(context, options, block)


if @path if @path
@variable, @variable_counter = retrieve_variable(@path) @variable, @variable_counter = retrieve_variable(@path)
@template_keys = retrieve_template_keys
else else
paths.map! { |path| retrieve_variable(path).unshift(path) } paths.map! { |path| retrieve_variable(path).unshift(path) }
end end
Expand All @@ -358,62 +359,55 @@ def collection
end end


def collection_from_object def collection_from_object
if @object.respond_to?(:to_ary) @object.to_ary if @object.respond_to?(:to_ary)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really need a method like try that only sends the method if the receiver responds to it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't. The current code is fine.

@object.to_ary
end
end end


def find_partial def find_partial
if path = @path if path = @path
locals = @locals.keys find_template(path, @template_keys)
locals << @variable
locals << @variable_counter if @collection
find_template(path, locals)
end end
end end


def find_template(path=@path, locals=@locals.keys) def find_template(path, locals)
prefixes = path.include?(?/) ? [] : @lookup_context.prefixes prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
@lookup_context.find_template(path, prefixes, true, locals, @details) @lookup_context.find_template(path, prefixes, true, locals, @details)
end end


def collection_with_template def collection_with_template
segments, locals, template = [], @locals, @template view, locals, template = @view, @locals, @template
as, counter = @variable, @variable_counter as, counter = @variable, @variable_counter


if layout = @options[:layout] if layout = @options[:layout]
layout = find_template(layout, @locals.keys + [@variable, @variable_counter]) layout = find_template(layout, @template_keys)
end end


locals[counter] = -1 index = -1

@collection.map do |object|
@collection.each do |object| locals[as] = object
locals[counter] += 1 locals[counter] = (index += 1)
locals[as] = object


content = template.render(@view, locals) content = template.render(view, locals)
content = layout.render(@view, locals) { content } if layout content = layout.render(view, locals) { content } if layout
segments << content content
end end

segments
end end


def collection_without_template def collection_without_template
segments, locals, collection_data = [], @locals, @collection_data view, locals, collection_data = @view, @locals, @collection_data
index, template, cache = -1, nil, {} cache = {}
keys = @locals.keys keys = @locals.keys


@collection.each_with_index do |object, i| index = -1
path, *data = collection_data[i] @collection.map do |object|
template = (cache[path] ||= find_template(path, keys + data)) index += 1
locals[data[0]] = object path, as, counter = collection_data[index]
locals[data[1]] = (index += 1)
segments << template.render(@view, locals)
end


@template = template locals[as] = object
segments locals[counter] = index

template = (cache[path] ||= find_template(path, keys + [as, counter]))
template.render(view, locals)
end
end end


def partial_path(object = @object) def partial_path(object = @object)
Expand Down Expand Up @@ -453,6 +447,13 @@ def merge_prefix_into_object_path(prefix, object_path)
end end
end end


def retrieve_template_keys
keys = @locals.keys
keys << @variable
keys << @variable_counter if @collection
keys
end

def retrieve_variable(path) def retrieve_variable(path)
variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym) variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym)
variable_counter = :"#{variable}_counter" if @collection variable_counter = :"#{variable}_counter" if @collection
Expand Down