mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-20 11:20:41 -07:00
Handle BlockBody#blank? at parse time (#1287)
This commit is contained in:
@@ -130,6 +130,26 @@ module Liquid
|
|||||||
@blank
|
@blank
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Remove blank strings in the block body for a control flow tag (e.g. `if`, `for`, `case`, `unless`)
|
||||||
|
# with a blank body.
|
||||||
|
#
|
||||||
|
# For example, in a conditional assignment like the following
|
||||||
|
#
|
||||||
|
# ```
|
||||||
|
# {% if size > max_size %}
|
||||||
|
# {% assign size = max_size %}
|
||||||
|
# {% endif %}
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# we assume the intention wasn't to output the blank spaces in the `if` tag's block body, so this method
|
||||||
|
# will remove them to reduce the render output size.
|
||||||
|
#
|
||||||
|
# Note that it is now preferred to use the `liquid` tag for this use case.
|
||||||
|
def remove_blank_strings
|
||||||
|
raise "remove_blank_strings only support being called on a blank block body" unless @blank
|
||||||
|
@nodelist.reject! { |node| node.instance_of?(String) }
|
||||||
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
render_to_output_buffer(context, +'')
|
render_to_output_buffer(context, +'')
|
||||||
end
|
end
|
||||||
@@ -143,10 +163,8 @@ module Liquid
|
|||||||
|
|
||||||
if node.instance_of?(String)
|
if node.instance_of?(String)
|
||||||
output << node
|
output << node
|
||||||
elsif node.instance_of?(Variable)
|
|
||||||
render_node(context, output, node)
|
|
||||||
else
|
else
|
||||||
render_node(context, node.blank? ? +'' : output, node)
|
render_node(context, output, node)
|
||||||
# If we get an Interrupt that means the block must stop processing. An
|
# If we get an Interrupt that means the block must stop processing. An
|
||||||
# Interrupt is any command that stops block execution such as {% break %}
|
# Interrupt is any command that stops block execution such as {% break %}
|
||||||
# or {% continue %}. These tags may also occur through Block or Include tags.
|
# or {% continue %}. These tags may also occur through Block or Include tags.
|
||||||
|
|||||||
@@ -25,10 +25,9 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render_to_output_buffer(context, output)
|
def render_to_output_buffer(context, output)
|
||||||
previous_output_size = output.bytesize
|
capture_output = render(context)
|
||||||
super
|
context.scopes.last[@to] = capture_output
|
||||||
context.scopes.last[@to] = output
|
context.resource_limits.assign_score += capture_output.bytesize
|
||||||
context.resource_limits.assign_score += (output.bytesize - previous_output_size)
|
|
||||||
output
|
output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ module Liquid
|
|||||||
def parse(tokens)
|
def parse(tokens)
|
||||||
body = BlockBody.new
|
body = BlockBody.new
|
||||||
body = @blocks.last.attachment while parse_body(body, tokens)
|
body = @blocks.last.attachment while parse_body(body, tokens)
|
||||||
|
if blank?
|
||||||
|
@blocks.each { |condition| condition.attachment.remove_blank_strings }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def nodelist
|
def nodelist
|
||||||
|
|||||||
@@ -59,8 +59,13 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def parse(tokens)
|
def parse(tokens)
|
||||||
return unless parse_body(@for_block, tokens)
|
if parse_body(@for_block, tokens)
|
||||||
parse_body(@else_block, tokens)
|
parse_body(@else_block, tokens)
|
||||||
|
end
|
||||||
|
if blank?
|
||||||
|
@for_block.remove_blank_strings
|
||||||
|
@else_block&.remove_blank_strings
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def nodelist
|
def nodelist
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ module Liquid
|
|||||||
def parse(tokens)
|
def parse(tokens)
|
||||||
while parse_body(@blocks.last.attachment, tokens)
|
while parse_body(@blocks.last.attachment, tokens)
|
||||||
end
|
end
|
||||||
|
if blank?
|
||||||
|
@blocks.each { |condition| condition.attachment.remove_blank_strings }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def unknown_tag(tag, markup, tokens)
|
def unknown_tag(tag, markup, tokens)
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ class TemplateTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
|
def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
|
||||||
t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
|
t = Template.parse("{% for a in (1..100) %}x{% assign foo = 1 %} {% endfor %}")
|
||||||
t.render!
|
t.render!
|
||||||
assert(t.resource_limits.assign_score > 0)
|
assert(t.resource_limits.assign_score > 0)
|
||||||
assert(t.resource_limits.render_score > 0)
|
assert(t.resource_limits.render_score > 0)
|
||||||
@@ -215,7 +215,7 @@ class TemplateTest < Minitest::Test
|
|||||||
|
|
||||||
def test_default_resource_limits_unaffected_by_render_with_context
|
def test_default_resource_limits_unaffected_by_render_with_context
|
||||||
context = Context.new
|
context = Context.new
|
||||||
t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
|
t = Template.parse("{% for a in (1..100) %}x{% assign foo = 1 %} {% endfor %}")
|
||||||
t.render!(context)
|
t.render!(context)
|
||||||
assert(context.resource_limits.assign_score > 0)
|
assert(context.resource_limits.assign_score > 0)
|
||||||
assert(context.resource_limits.render_score > 0)
|
assert(context.resource_limits.render_score > 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user