Bump Liquid to 5.11.0 (#2012)

This commit reverts the Inline Snippets tag (#2001) and bumps
Liquid to 5.11. For now, the inclusion of Inline Snippets
in the latest Liquid release is being treated as a bug.

While #2001 does implement the scope contained in RFC#1916,
we need to take a step back to make sure we’re setting our
sights high enough with this feature, and that we’re truly
supporting theme developers in the ways they need.

If you have any feedback, please leave a comment on RFC#1916.

- Liquid Developer Tools
This commit is contained in:
Guilherme Carreiro
2025-11-19 18:03:23 +01:00
committed by GitHub
parent cbd8a0a2ee
commit 32b50ecafe
33 changed files with 163 additions and 1326 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ module Liquid
# @param file_system The default file system that is used
# to load templates from.
# @param error_mode [Symbol] The default error mode for all templates
# (either :rigid, :strict, :warn, or :lax).
# (either :strict2, :strict, :warn, or :lax).
# @param exception_renderer [Proc] The exception renderer that is used to
# render exceptions.
# @yieldparam environment [Environment] The environment instance that is being built.
-3
View File
@@ -5,7 +5,6 @@
block_tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: {% %{tag} %}{% end%{tag} %}"
assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"
capture: "Syntax Error in 'capture' - Valid syntax: capture [var]"
snippet: "Syntax Error in 'snippet' - Valid syntax: snippet [var]"
case: "Syntax Error in 'case' - Valid syntax: case [condition]"
case_invalid_when: "Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %}"
case_invalid_else: "Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) "
@@ -20,7 +19,6 @@
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
invalid_template_encoding: "Invalid template encoding"
render: "Syntax error in tag 'render' - Template name must be a quoted string"
render_invalid_template_name: "Syntax error in tag 'render' - Expected a string or identifier, found %{found}"
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
table_row_invalid_attribute: "Invalid attribute '%{attribute}' in tablerow loop. Valid attributes are cols, limit, offset, and range"
tag_never_closed: "'%{block_name}' tag was never closed"
@@ -31,6 +29,5 @@
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
argument:
include: "Argument error in tag 'include' - Illegal template name"
render: "Argument error in tag 'render' - Dynamically chosen templates are not allowed"
disabled:
tag: "usage is not allowed in this context"
+4 -4
View File
@@ -55,15 +55,15 @@ module Liquid
end
def parse_expression(markup, safe: false)
if !safe && @error_mode == :rigid
if !safe && @error_mode == :strict2
# parse_expression is a widely used API. To maintain backward
# compatibility while raising awareness about rigid parser standards,
# compatibility while raising awareness about strict2 parser standards,
# the safe flag supports API users make a deliberate decision.
#
# In rigid mode, markup MUST come from a string returned by the parser
# In strict2 mode, markup MUST come from a string returned by the parser
# (e.g., parser.expression). We're not calling the parser here to
# prevent redundant parser overhead.
raise Liquid::InternalError, "unsafe parse_expression cannot be used in rigid mode"
raise Liquid::InternalError, "unsafe parse_expression cannot be used in strict2 mode"
end
Expression.parse(markup, @string_scanner, @expression_cache)
+18 -10
View File
@@ -7,16 +7,19 @@ module Liquid
# It's basically doing the same thing the {#parse_with_selected_parser},
# except this will try the strict parser regardless of the error mode,
# and fall back to the lax parser if the error mode is lax or warn,
# except when in rigid mode where it uses the rigid parser.
# except when in strict2 mode where it uses the strict2 parser.
#
# @deprecated Use {#parse_with_selected_parser} instead.
def strict_parse_with_error_mode_fallback(markup)
return rigid_parse_with_error_context(markup) if rigid_mode?
return strict2_parse_with_error_context(markup) if strict2_mode?
strict_parse_with_error_context(markup)
rescue SyntaxError => e
case parse_context.error_mode
when :rigid
rigid_warn
raise
when :strict2
raise
when :strict
raise
@@ -28,12 +31,13 @@ module Liquid
def parse_with_selected_parser(markup)
case parse_context.error_mode
when :rigid then rigid_parse_with_error_context(markup)
when :strict then strict_parse_with_error_context(markup)
when :lax then lax_parse(markup)
when :rigid then rigid_warn && strict2_parse_with_error_context(markup)
when :strict2 then strict2_parse_with_error_context(markup)
when :strict then strict_parse_with_error_context(markup)
when :lax then lax_parse(markup)
when :warn
begin
rigid_parse_with_error_context(markup)
strict2_parse_with_error_context(markup)
rescue SyntaxError => e
parse_context.warnings << e
lax_parse(markup)
@@ -41,14 +45,18 @@ module Liquid
end
end
def rigid_mode?
parse_context.error_mode == :rigid
def strict2_mode?
parse_context.error_mode == :strict2 || parse_context.error_mode == :rigid
end
private
def rigid_parse_with_error_context(markup)
rigid_parse(markup)
def rigid_warn
Deprecations.warn(':rigid', ':strict2')
end
def strict2_parse_with_error_context(markup)
strict2_parse(markup)
rescue SyntaxError => e
e.line_number = line_number
e.markup_context = markup_context(markup)
-22
View File
@@ -1,22 +0,0 @@
# frozen_string_literal: true
module Liquid
class SnippetDrop < Drop
attr_reader :body, :name, :filename
def initialize(body, name, filename)
super()
@body = body
@name = name
@filename = filename
end
def to_partial
@body
end
def to_s
'SnippetDrop'
end
end
end
-2
View File
@@ -20,7 +20,6 @@ require_relative "tags/raw"
require_relative "tags/render"
require_relative "tags/cycle"
require_relative "tags/doc"
require_relative "tags/snippet"
module Liquid
module Tags
@@ -45,7 +44,6 @@ module Liquid
'echo' => Echo,
'tablerow' => TableRow,
'doc' => Doc,
'snippet' => Snippet,
}.freeze
end
end
+4 -4
View File
@@ -86,7 +86,7 @@ module Liquid
private
def rigid_parse(markup)
def strict2_parse(markup)
parser = @parse_context.new_parser(markup)
@left = safe_parse_expression(parser)
parser.consume(:end_of_string)
@@ -107,14 +107,14 @@ module Liquid
def record_when_condition(markup)
body = new_body
if rigid_mode?
parse_rigid_when(markup, body)
if strict2_mode?
parse_strict2_when(markup, body)
else
parse_lax_when(markup, body)
end
end
def parse_rigid_when(markup, body)
def parse_strict2_when(markup, body)
parser = @parse_context.new_parser(markup)
loop do
+1 -1
View File
@@ -56,7 +56,7 @@ module Liquid
private
# cycle [name:] expression(, expression)*
def rigid_parse(markup)
def strict2_parse(markup)
p = @parse_context.new_parser(markup)
@variables = []
+1 -1
View File
@@ -111,7 +111,7 @@ module Liquid
private
def rigid_parse(markup)
def strict2_parse(markup)
strict_parse(markup)
end
+1 -1
View File
@@ -66,7 +66,7 @@ module Liquid
private
def rigid_parse(markup)
def strict2_parse(markup)
strict_parse(markup)
end
+1 -1
View File
@@ -84,7 +84,7 @@ module Liquid
alias_method :parse_context, :options
private :parse_context
def rigid_parse(markup)
def strict2_parse(markup)
p = @parse_context.new_parser(markup)
@template_name_expr = safe_parse_expression(p)
+17 -23
View File
@@ -27,7 +27,7 @@ module Liquid
# @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
class Render < Tag
FOR = 'for'
SYNTAX = /(#{QuotedString}+|#{VariableSegment}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
SYNTAX = /(#{QuotedString}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
disable_tags "include"
@@ -47,23 +47,21 @@ module Liquid
end
def render_tag(context, output)
template = context.evaluate(@template_name_expr)
# The expression should be a String literal, which parses to a String object
template_name = @template_name_expr
raise ::ArgumentError unless template_name.is_a?(String)
if template.respond_to?(:to_partial)
partial = template.to_partial
template_name = template.filename
context_variable_name = @alias_name || template.name
elsif @template_name_expr.is_a?(String)
partial = PartialCache.load(template, context: context, parse_context: parse_context)
template_name = partial.name
context_variable_name = @alias_name || template_name.split('/').last
else
raise ::ArgumentError
end
partial = PartialCache.load(
template_name,
context: context,
parse_context: parse_context,
)
context_variable_name = @alias_name || template_name.split('/').last
render_partial_func = ->(var, forloop) {
inner_context = context.new_isolated_subcontext
inner_context.template_name = template_name
inner_context.template_name = partial.name
inner_context.partial = true
inner_context['forloop'] = forloop if forloop
@@ -87,10 +85,10 @@ module Liquid
end
# render (string) (with|for expression)? (as id)? (key: value)*
def rigid_parse(markup)
def strict2_parse(markup)
p = @parse_context.new_parser(markup)
@template_name_expr = parse_expression(rigid_template_name(p), safe: true)
@template_name_expr = parse_expression(strict2_template_name(p), safe: true)
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")
@@ -103,18 +101,14 @@ module Liquid
key = p.consume
p.consume(:colon)
@attributes[key] = safe_parse_expression(p)
p.consume?(:comma) # optional comma
p.consume?(:comma)
end
p.consume(:end_of_string)
end
def rigid_template_name(p)
return p.consume(:string) if p.look(:string)
return p.consume(:id) if p.look(:id)
found = p.consume || "nothing"
raise SyntaxError, options[:locale].t("errors.syntax.render_invalid_template_name", found: found)
def strict2_template_name(p)
p.consume(:string)
end
def strict_parse(markup)
-45
View File
@@ -1,45 +0,0 @@
# frozen_string_literal: true
module Liquid
# @liquid_public_docs
# @liquid_type tag
# @liquid_category variable
# @liquid_name snippet
# @liquid_summary
# Creates a new inline snippet.
# @liquid_description
# You can create inline snippets to make your Liquid code more modular.
# @liquid_syntax
# {% snippet snippet_name %}
# value
# {% endsnippet %}
class Snippet < Block
def initialize(tag_name, markup, options)
super
p = @parse_context.new_parser(markup)
if p.look(:id)
@to = p.consume(:id)
p.consume(:end_of_string)
else
raise SyntaxError, options[:locale].t("errors.syntax.snippet")
end
end
def render_to_output_buffer(context, output)
snippet_drop = SnippetDrop.new(@body, @to, context.template_name)
context.scopes.last[@to] = snippet_drop
context.resource_limits.increment_assign_score(assign_score_of(snippet_drop))
output
end
def blank?
true
end
private
def assign_score_of(snippet_drop)
snippet_drop.body.nodelist.sum { |node| node.to_s.bytesize }
end
end
end
+1 -1
View File
@@ -34,7 +34,7 @@ module Liquid
parse_with_selected_parser(markup)
end
def rigid_parse(markup)
def strict2_parse(markup)
p = @parse_context.new_parser(markup)
@variable_name = p.consume(:id)
+1 -1
View File
@@ -25,7 +25,7 @@ module Liquid
# :lax acts like liquid 2.5 and silently ignores malformed tags in most cases.
# :warn is the default and will give deprecation warnings when invalid syntax is used.
# :strict enforces correct syntax for most tags
# :rigid enforces correct syntax for all tags
# :strict2 enforces correct syntax for all tags
def error_mode=(mode)
Deprecations.warn("Template.error_mode=", "Environment#error_mode=")
Environment.default.error_mode = mode
+3 -3
View File
@@ -74,14 +74,14 @@ module Liquid
p.consume(:end_of_string)
end
def rigid_parse(markup)
def strict2_parse(markup)
@filters = []
p = @parse_context.new_parser(markup)
return if p.look(:end_of_string)
@name = parse_context.safe_parse_expression(p)
@filters << rigid_parse_filter_expressions(p) while p.consume?(:pipe)
@filters << strict2_parse_filter_expressions(p) while p.consume?(:pipe)
p.consume(:end_of_string)
end
@@ -156,7 +156,7 @@ module Liquid
# argument = (positional_argument | keyword_argument)
# positional_argument = expression
# keyword_argument = id ":" expression
def rigid_parse_filter_expressions(p)
def strict2_parse_filter_expressions(p)
filtername = p.consume(:id)
filter_args = []
keyword_args = {}
+1 -1
View File
@@ -2,5 +2,5 @@
# frozen_string_literal: true
module Liquid
VERSION = "5.10.0"
VERSION = "5.11.0"
end