Skip to content

Commit

Permalink
Add end tag support
Browse files Browse the repository at this point in the history
- Not allowed for `comment` nor `raw`
  • Loading branch information
charlespwd committed Sep 3, 2024
1 parent 0b93182 commit 354a0f6
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 6 deletions.
10 changes: 7 additions & 3 deletions lib/liquid/block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ def unknown_tag(tag_name, _markup, _tokenizer)
end

# @api private
def self.raise_unknown_tag(tag, block_name, block_delimiter, parse_context)
def self.raise_unknown_tag(tag, block_name, block_delimiter, parse_context, supports_end_tag = true)
if tag == 'else'
raise SyntaxError, parse_context.locale.t(
"errors.syntax.unexpected_else",
block_name: block_name,
)
elsif tag.start_with?('end')
raise SyntaxError, parse_context.locale.t(
"errors.syntax.invalid_delimiter",
supports_end_tag ? "errors.syntax.invalid_delimiter" : "errors.syntax.invalid_delimiter_no_end",
tag: tag,
block_name: block_name,
block_delimiter: block_delimiter,
Expand All @@ -64,6 +64,10 @@ def block_delimiter
@block_delimiter ||= "end#{block_name}"
end

def supports_end_tag?
true
end

private

# @api public
Expand All @@ -81,7 +85,7 @@ def parse_body(body, tokens)
body.parse(tokens, parse_context) do |end_tag_name, end_tag_params|
@blank &&= body.blank?

return false if end_tag_name == block_delimiter
return false if end_tag_name == block_delimiter || (supports_end_tag? && end_tag_name == 'end')
raise_tag_never_closed(block_name) unless end_tag_name

# this tag is not registered with the system
Expand Down
2 changes: 1 addition & 1 deletion lib/liquid/block_body.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def freeze

# @api private
def self.unknown_tag_in_liquid_tag(tag, parse_context)
Block.raise_unknown_tag(tag, 'liquid', '%}', parse_context)
Block.raise_unknown_tag(tag, 'liquid', '%}', parse_context, false)
end

# @api private
Expand Down
3 changes: 2 additions & 1 deletion lib/liquid/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
if: "Syntax Error in tag 'if' - Valid syntax: if [expression]"
include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"
inline_comment_invalid: "Syntax error in tag '#' - Each line of comments must be prefixed by the '#' character"
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use end or %{block_delimiter}"
invalid_delimiter_no_end: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
render: "Syntax error in tag 'render' - Template name must be a quoted string"
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
tag_never_closed: "'%{block_name}' tag was never closed"
Expand Down
4 changes: 4 additions & 0 deletions lib/liquid/tags/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def render_to_output_buffer(_context, output)
def unknown_tag(_tag, _markup, _tokens)
end

def supports_end_tag?
false
end

def blank?
true
end
Expand Down
4 changes: 4 additions & 0 deletions lib/liquid/tags/raw.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def initialize(tag_name, markup, parse_context)
ensure_valid_markup(tag_name, markup, parse_context)
end

def supports_end_tag?
false
end

def parse(tokens)
@body = +''
while (token = tokens.shift)
Expand Down
24 changes: 23 additions & 1 deletion test/integration/block_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,31 @@
class BlockTest < Minitest::Test
include Liquid

def test_simple_end_tag
assert_template_result('you rock', '{% if true %}you rock{% end %}')
assert_template_result('you rock', '{% if true %}{% unless false %}you rock{% end %}{% end %}')
end

def test_unexpected_end_tag
source = '{% if true %}{% endunless %}'
assert_match_syntax_error("Liquid syntax error (line 1): 'endunless' is not a valid delimiter for if tags. use endif", source)
assert_match_syntax_error("Liquid syntax error (line 1): 'endunless' is not a valid delimiter for if tags. use end or endif", source)
end

def test_end_closes_closest_open_tag
source = '{% if true %}{% unless true %}{% end %}{% endunless %}'
assert_match_syntax_error("Liquid syntax error (line 1): 'endunless' is not a valid delimiter for if tags. use end or endif", source)
end

# comments are special and can't be closed by `end`
def test_unexpected_end_tag_comment
source = '{% comment %}{% end %}'
assert_match_syntax_error("Liquid syntax error (line 1): 'comment' tag was never closed", source)
end

# raw is special and can't be closed by `end`
def test_unexpected_end_tag_raw
source = '{% raw %}{% end %}'
assert_match_syntax_error("Liquid syntax error (line 1): 'raw' tag was never closed", source)
end

def test_with_custom_tag
Expand Down
1 change: 1 addition & 0 deletions test/integration/tags/if_else_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def test_if
' {% if true %} this text should go into the output {% endif %} ',
)
assert_template_result(' you rock ?', '{% if false %} you suck {% endif %} {% if true %} you rock {% endif %}?')
assert_template_result(' you rock ?', '{% if false %} you suck {% endif %} {% if true %} you rock {% end %}?')
end

def test_literal_comparisons
Expand Down
14 changes: 14 additions & 0 deletions test/integration/tags/liquid_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ def test_cannot_close_blocks_created_before_a_liquid_tag
42
{%- liquid endif -%}
LIQUID
assert_match_syntax_error("syntax error (line 3): 'end' is not a valid delimiter for liquid tags. use %}", <<~LIQUID)
{%- if true -%}
42
{%- liquid end -%}
LIQUID
end

def test_liquid_tag_in_raw
Expand All @@ -123,6 +128,15 @@ def test_nested_liquid_tags
endif
-%}
LIQUID

assert_template_result('good', <<~LIQUID)
{%- liquid
liquid
if true
echo "good"
end
-%}
LIQUID
end

def test_nested_liquid_tags_on_same_line
Expand Down
4 changes: 4 additions & 0 deletions test/integration/tags/raw_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def test_tag_in_raw
'{% comment %} test {% endcomment %}',
'{% raw %}{% comment %} test {% endcomment %}{% endraw %}',
)
assert_template_result(
'',
'{% comment %} {% if true %}{% end %} {% endcomment %}',
)
end

def test_output_in_raw
Expand Down
1 change: 1 addition & 0 deletions test/integration/tags/standard_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def test_has_a_block_which_does_nothing
assert_template_result('', '{%comment%}{%blabla%}{%endcomment%}')
assert_template_result('', '{% comment %}{% blabla %}{% endcomment %}')
assert_template_result('', '{%comment%}{% endif %}{%endcomment%}')
assert_template_result('', '{%comment%}{% end %}{%endcomment%}')
assert_template_result('', '{% comment %}{% endwhatever %}{% endcomment %}')
assert_template_result('', '{% comment %}{% raw %} {{%%%%}} }} { {% endcomment %} {% comment {% endraw %} {% endcomment %}')
assert_template_result('', '{% comment %}{% " %}{% endcomment %}')
Expand Down

0 comments on commit 354a0f6

Please sign in to comment.