mirror of
https://github.com/Shopify/liquid.git
synced 2026-01-26 12:14:58 +00:00
Allow render tag to recognize drops that respond to to_partial
This commit is contained in:
parent
0cc6cdd553
commit
db350c54ff
@ -1,5 +1,6 @@
|
|||||||
<p>Hello world!</p>
|
<p>Hello world!</p>
|
||||||
|
|
||||||
<p>It is {{ date }}</p>
|
<p>It is {{date}}</p>
|
||||||
|
|
||||||
<p>Check out the <a href="/products">Products</a> screen</p>
|
|
||||||
|
<p>Check out the <a href="/products">Products</a> screen </p>
|
||||||
|
|||||||
@ -31,5 +31,6 @@
|
|||||||
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
|
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
|
||||||
argument:
|
argument:
|
||||||
include: "Argument error in tag 'include' - Illegal template name"
|
include: "Argument error in tag 'include' - Illegal template name"
|
||||||
|
render: "Argument error in tag 'render' - Dynamically chosen templates are not allowed"
|
||||||
disabled:
|
disabled:
|
||||||
tag: "usage is not allowed in this context"
|
tag: "usage is not allowed in this context"
|
||||||
|
|||||||
@ -2,11 +2,16 @@
|
|||||||
|
|
||||||
module Liquid
|
module Liquid
|
||||||
class SnippetDrop < Drop
|
class SnippetDrop < Drop
|
||||||
attr_reader :body
|
attr_reader :body, :name
|
||||||
|
|
||||||
def initialize(body)
|
def initialize(body, name)
|
||||||
super()
|
super()
|
||||||
@body = body
|
@body = body
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_partial
|
||||||
|
@body
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
|
|||||||
@ -47,40 +47,30 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_tag(context, output)
|
def render_tag(context, output)
|
||||||
template_name = @template_name_expr
|
template = context.evaluate(@template_name_expr)
|
||||||
is_inline = template_name.is_a?(VariableLookup)
|
|
||||||
is_file = template_name.is_a?(String)
|
|
||||||
|
|
||||||
if is_inline
|
if template.respond_to?(:to_partial)
|
||||||
template_name = template_name.name
|
partial = template.to_partial
|
||||||
snippet_drop = context[template_name]
|
template_name = template.name
|
||||||
raise ::ArgumentError unless snippet_drop.is_a?(Liquid::SnippetDrop)
|
elsif @template_name_expr.is_a?(String)
|
||||||
|
partial = PartialCache.load(template, context: context, parse_context: parse_context)
|
||||||
partial = snippet_drop.body
|
template_name = partial.name
|
||||||
else
|
else
|
||||||
raise ::ArgumentError unless is_file
|
raise ::ArgumentError, parse_context.locale.t("errors.argument.render")
|
||||||
|
|
||||||
partial = PartialCache.load(template_name, context: context, parse_context: parse_context)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context_variable_name = @alias_name || template_name.split('/').last
|
context_variable_name = @alias_name || template_name.split('/').last
|
||||||
|
|
||||||
render_partial_func = ->(var, forloop) {
|
render_partial_func = ->(var, forloop) {
|
||||||
inner_context = context.new_isolated_subcontext
|
inner_context = context.new_isolated_subcontext
|
||||||
|
inner_context.template_name = template_name
|
||||||
if is_file
|
inner_context.partial = true
|
||||||
inner_context.template_name = partial.name
|
inner_context['forloop'] = forloop if forloop
|
||||||
inner_context.partial = true
|
|
||||||
end
|
|
||||||
|
|
||||||
inner_context['forloop'] = forloop if forloop
|
|
||||||
|
|
||||||
@attributes.each do |key, value|
|
@attributes.each do |key, value|
|
||||||
inner_context[key] = context.evaluate(value)
|
inner_context[key] = context.evaluate(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
inner_context[context_variable_name] = var unless var.nil?
|
inner_context[context_variable_name] = var unless var.nil?
|
||||||
|
|
||||||
partial.render_to_output_buffer(inner_context, output)
|
partial.render_to_output_buffer(inner_context, output)
|
||||||
forloop&.send(:increment!)
|
forloop&.send(:increment!)
|
||||||
}
|
}
|
||||||
@ -113,7 +103,6 @@ module Liquid
|
|||||||
key = p.consume
|
key = p.consume
|
||||||
p.consume(:colon)
|
p.consume(:colon)
|
||||||
@attributes[key] = safe_parse_expression(p)
|
@attributes[key] = safe_parse_expression(p)
|
||||||
|
|
||||||
p.consume?(:comma) # optional comma
|
p.consume?(:comma) # optional comma
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_to_output_buffer(context, output)
|
def render_to_output_buffer(context, output)
|
||||||
snippet_drop = SnippetDrop.new(@body)
|
snippet_drop = SnippetDrop.new(@body, @to)
|
||||||
context.scopes.last[@to] = snippet_drop
|
context.scopes.last[@to] = snippet_drop
|
||||||
|
|
||||||
snippet_size = @body.nodelist.sum { |node| node.to_s.bytesize }
|
snippet_size = @body.nodelist.sum { |node| node.to_s.bytesize }
|
||||||
|
|||||||
@ -101,10 +101,11 @@ class RenderTagTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_dynamically_choosen_templates_are_not_allowed
|
def test_dynamically_chosen_templates_are_not_allowed
|
||||||
assert_raises(::ArgumentError) do
|
error = assert_raises(::ArgumentError) do
|
||||||
Template.parse('{% assign name = "snippet" %}{% render name %}').render!
|
Template.parse('{% assign name = "snippet" %}{% render name %}').render!
|
||||||
end
|
end
|
||||||
|
assert_equal("Argument error in tag 'render' - Dynamically chosen templates are not allowed", error.message)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rigid_parsing_errors
|
def test_rigid_parsing_errors
|
||||||
@ -296,6 +297,13 @@ class RenderTagTest < Minitest::Test
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_render_tag_with_snippet_drop
|
||||||
|
assert_template_result(
|
||||||
|
"Hello from snippet",
|
||||||
|
"{% snippet my_snippet %}Hello from snippet{% endsnippet %}{% render my_snippet %}",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def test_render_tag_renders_error_with_template_name
|
def test_render_tag_renders_error_with_template_name
|
||||||
assert_template_result(
|
assert_template_result(
|
||||||
'Liquid error (foo line 1): standard error',
|
'Liquid error (foo line 1): standard error',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user