Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions lib/liquid/tags/include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ module Liquid
class Include < Tag
prepend Tag::Disableable

SYNTAX = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
FOR = 'for'
SYNTAX = /(#{QuotedFragment}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
Syntax = SYNTAX

attr_reader :template_name_expr, :variable_name_expr, :attributes
Expand Down Expand Up @@ -84,12 +85,18 @@ def render_to_output_buffer(context, output)
alias_method :parse_context, :options
private :parse_context

def for_loop?
@is_for_loop
end

def strict2_parse(markup)
p = @parse_context.new_parser(markup)

@template_name_expr = safe_parse_expression(p)
@variable_name_expr = safe_parse_expression(p) if p.id?("for") || p.id?("with")
with_or_for = p.id?("for") || p.id?("with")
@variable_name_expr = safe_parse_expression(p) if with_or_for
@alias_name = p.consume(:id) if p.id?("as")
@is_for_loop = (with_or_for == FOR)

p.consume?(:comma)

Expand All @@ -111,11 +118,13 @@ def strict_parse(markup)
def lax_parse(markup)
if markup =~ SYNTAX
template_name = Regexp.last_match(1)
variable_name = Regexp.last_match(3)
with_or_for = Regexp.last_match(3)
variable_name = Regexp.last_match(4)

@alias_name = Regexp.last_match(5)
@alias_name = Regexp.last_match(6)
@variable_name_expr = variable_name ? parse_expression(variable_name) : nil
@template_name_expr = parse_expression(template_name)
@is_for_loop = (with_or_for == FOR)
@attributes = {}

markup.scan(TagAttributes) do |key, value|
Expand Down
45 changes: 45 additions & 0 deletions test/integration/tags/include_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -439,4 +439,49 @@ def test_include_attribute_with_invalid_expression
assert_match(/Unexpected character =/, error.message)
end
end

def test_include_for_loop_true_with_for_keyword
with_error_modes(:lax, :strict, :strict2) do
template = Template.parse("{% include 'product' for products %}")
include_node = template.root.nodelist.first

assert(include_node.for_loop?, "Expected for_loop? to be true for 'for' keyword")
end
end

def test_include_for_loop_false_with_with_keyword
with_error_modes(:lax, :strict, :strict2) do
template = Template.parse("{% include 'product' with product %}")
include_node = template.root.nodelist.first

refute(include_node.for_loop?, "Expected for_loop? to be false for 'with' keyword")
end
end

def test_include_for_loop_false_without_keyword
with_error_modes(:lax, :strict, :strict2) do
template = Template.parse("{% include 'header' %}")
include_node = template.root.nodelist.first

refute(include_node.for_loop?, "Expected for_loop? to be false when no keyword")
end
end

def test_include_for_loop_with_alias
with_error_modes(:lax, :strict, :strict2) do
template = Template.parse("{% include 'product' for products as item %}")
include_node = template.root.nodelist.first

assert(include_node.for_loop?, "Expected for_loop? to be true for 'for' with alias")
end
end

def test_include_with_keyword_and_alias
with_error_modes(:lax, :strict, :strict2) do
template = Template.parse("{% include 'product' with products[0] as item %}")
include_node = template.root.nodelist.first

refute(include_node.for_loop?, "Expected for_loop? to be false for 'with' with alias")
end
end
end # IncludeTagTest
Loading