liquid 5.10.0 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +4 -6
- data/README.md +4 -4
- data/lib/liquid/condition.rb +54 -11
- data/lib/liquid/context.rb +1 -1
- data/lib/liquid/drop.rb +1 -1
- data/lib/liquid/environment.rb +1 -1
- data/lib/liquid/expression.rb +1 -1
- data/lib/liquid/i18n.rb +1 -1
- data/lib/liquid/locales/en.yml +0 -3
- data/lib/liquid/parse_context.rb +4 -4
- data/lib/liquid/parser_switching.rb +18 -10
- data/lib/liquid/resource_limits.rb +22 -5
- data/lib/liquid/standardfilters.rb +17 -0
- data/lib/liquid/tags/case.rb +5 -5
- data/lib/liquid/tags/cycle.rb +1 -1
- data/lib/liquid/tags/for.rb +1 -1
- data/lib/liquid/tags/if.rb +1 -1
- data/lib/liquid/tags/include.rb +1 -1
- data/lib/liquid/tags/render.rb +18 -24
- data/lib/liquid/tags/table_row.rb +1 -1
- data/lib/liquid/tags.rb +0 -2
- data/lib/liquid/template.rb +1 -1
- data/lib/liquid/tokenizer.rb +1 -1
- data/lib/liquid/utils.rb +3 -1
- data/lib/liquid/variable.rb +3 -3
- data/lib/liquid/variable_lookup.rb +5 -0
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +0 -1
- metadata +2 -4
- data/lib/liquid/snippet_drop.rb +0 -22
- data/lib/liquid/tags/snippet.rb +0 -45
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ede4a234547978b59f059b4a2939bfb3c91092952c45ef8616f7874c2f9902e3
|
|
4
|
+
data.tar.gz: 4f489720f234a848498a390a76ba89e97bfa6b5d8c708ac9b6de293748ce6dd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c0417cca5aece94bb341d38ba6e20deac2437fa453e926c296b6725858a35e845f25c548d1ddb364c675223667284ee088cf1fe76c151ef905b70cda08b977d3
|
|
7
|
+
data.tar.gz: ec169349a4b973bc11d5f52a2f4f20e7467eaecae1521cdec014b9e42f2de2cc955b1789f44e0249db95f9d8fc5d7659fed6897c699753f8f4111ce16c742b36
|
data/History.md
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
# Liquid Change Log
|
|
2
2
|
|
|
3
|
+
## 5.11.0
|
|
4
|
+
* Revert the Inline Snippets tag (#2001), treat its inclusion in the latest Liquid release as a bug, and allow for feedback on RFC#1916 to better support Liquid developers [Guilherme Carreiro]
|
|
5
|
+
* Rename the `:rigid` error mode to `:strict2` and display a warning when users attempt to use the `:rigid` mode [Guilherme Carreiro]
|
|
6
|
+
|
|
3
7
|
## 5.10.0
|
|
4
8
|
* Introduce support for Inline Snippets [Julia Boutin]
|
|
5
|
-
```
|
|
6
|
-
{%- snippet snowdevil -%}
|
|
7
|
-
Snowdevil
|
|
8
|
-
{%- endsnippet -%}
|
|
9
|
-
{% render snowdevil %}
|
|
10
|
-
```
|
|
11
9
|
|
|
12
10
|
## 5.9.0
|
|
13
11
|
* Introduce `:rigid` error mode for stricter, safer parsing of all tags [CP Clermont, Guilherme Carreiro]
|
data/README.md
CHANGED
|
@@ -103,10 +103,10 @@ Liquid also comes with different parsers that can be used when editing templates
|
|
|
103
103
|
when templates are invalid. You can enable this new parser like this:
|
|
104
104
|
|
|
105
105
|
```ruby
|
|
106
|
-
Liquid::Environment.default.error_mode = :
|
|
107
|
-
Liquid::Environment.default.error_mode = :strict
|
|
108
|
-
Liquid::Environment.default.error_mode = :warn
|
|
109
|
-
Liquid::Environment.default.error_mode = :lax
|
|
106
|
+
Liquid::Environment.default.error_mode = :strict2 # Raises a SyntaxError when invalid syntax is used in all tags
|
|
107
|
+
Liquid::Environment.default.error_mode = :strict # Raises a SyntaxError when invalid syntax is used in some tags
|
|
108
|
+
Liquid::Environment.default.error_mode = :warn # Adds strict errors to template.errors but continues as normal
|
|
109
|
+
Liquid::Environment.default.error_mode = :lax # The default mode, accepts almost anything.
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
If you want to set the error mode only on specific templates you can pass `:error_mode` as an option to `parse`:
|
data/lib/liquid/condition.rb
CHANGED
|
@@ -113,22 +113,65 @@ module Liquid
|
|
|
113
113
|
|
|
114
114
|
def equal_variables(left, right)
|
|
115
115
|
if left.is_a?(MethodLiteral)
|
|
116
|
-
|
|
117
|
-
return right.send(left.method_name)
|
|
118
|
-
else
|
|
119
|
-
return nil
|
|
120
|
-
end
|
|
116
|
+
return call_method_literal(left, right)
|
|
121
117
|
end
|
|
122
118
|
|
|
123
119
|
if right.is_a?(MethodLiteral)
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+
return call_method_literal(right, left)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
left == right
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def call_method_literal(literal, value)
|
|
127
|
+
method_name = literal.method_name
|
|
128
|
+
|
|
129
|
+
# If the object responds to the method (e.g., ActiveSupport is loaded), use it
|
|
130
|
+
if value.respond_to?(method_name)
|
|
131
|
+
value.send(method_name)
|
|
132
|
+
else
|
|
133
|
+
# Emulate ActiveSupport's blank?/empty? to make Liquid invariant
|
|
134
|
+
# to whether ActiveSupport is loaded or not
|
|
135
|
+
case method_name
|
|
136
|
+
when :blank?
|
|
137
|
+
liquid_blank?(value)
|
|
138
|
+
when :empty?
|
|
139
|
+
liquid_empty?(value)
|
|
126
140
|
else
|
|
127
|
-
|
|
141
|
+
false
|
|
128
142
|
end
|
|
129
143
|
end
|
|
144
|
+
end
|
|
130
145
|
|
|
131
|
-
|
|
146
|
+
# Implement blank? semantics matching ActiveSupport
|
|
147
|
+
# blank? returns true for nil, false, empty strings, whitespace-only strings,
|
|
148
|
+
# empty arrays, and empty hashes
|
|
149
|
+
def liquid_blank?(value)
|
|
150
|
+
case value
|
|
151
|
+
when NilClass, FalseClass
|
|
152
|
+
true
|
|
153
|
+
when TrueClass, Numeric
|
|
154
|
+
false
|
|
155
|
+
when String
|
|
156
|
+
# Blank if empty or whitespace only (matches ActiveSupport)
|
|
157
|
+
value.empty? || value.match?(/\A\s*\z/)
|
|
158
|
+
when Array, Hash
|
|
159
|
+
value.empty?
|
|
160
|
+
else
|
|
161
|
+
# Fall back to empty? if available, otherwise false
|
|
162
|
+
value.respond_to?(:empty?) ? value.empty? : false
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Implement empty? semantics
|
|
167
|
+
# Note: nil is NOT empty. empty? checks if a collection has zero elements.
|
|
168
|
+
def liquid_empty?(value)
|
|
169
|
+
case value
|
|
170
|
+
when String, Array, Hash
|
|
171
|
+
value.empty?
|
|
172
|
+
else
|
|
173
|
+
value.respond_to?(:empty?) ? value.empty? : false
|
|
174
|
+
end
|
|
132
175
|
end
|
|
133
176
|
|
|
134
177
|
def interpret_condition(left, right, op, context)
|
|
@@ -154,8 +197,8 @@ module Liquid
|
|
|
154
197
|
end
|
|
155
198
|
|
|
156
199
|
def deprecated_default_context
|
|
157
|
-
warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated" \
|
|
158
|
-
"
|
|
200
|
+
warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated " \
|
|
201
|
+
"and will be removed from Liquid 6.0.0.")
|
|
159
202
|
Context.new
|
|
160
203
|
end
|
|
161
204
|
|
data/lib/liquid/context.rb
CHANGED
data/lib/liquid/drop.rb
CHANGED
data/lib/liquid/environment.rb
CHANGED
|
@@ -34,7 +34,7 @@ module Liquid
|
|
|
34
34
|
# @param file_system The default file system that is used
|
|
35
35
|
# to load templates from.
|
|
36
36
|
# @param error_mode [Symbol] The default error mode for all templates
|
|
37
|
-
# (either :
|
|
37
|
+
# (either :strict2, :strict, :warn, or :lax).
|
|
38
38
|
# @param exception_renderer [Proc] The exception renderer that is used to
|
|
39
39
|
# render exceptions.
|
|
40
40
|
# @yieldparam environment [Environment] The environment instance that is being built.
|
data/lib/liquid/expression.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Liquid
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def inner_parse(markup, ss, cache)
|
|
58
|
-
if
|
|
58
|
+
if markup.start_with?("(") && markup.end_with?(")") && markup =~ RANGES_REGEX
|
|
59
59
|
return RangeLookup.parse(
|
|
60
60
|
Regexp.last_match(1),
|
|
61
61
|
Regexp.last_match(2),
|
data/lib/liquid/i18n.rb
CHANGED
|
@@ -28,7 +28,7 @@ module Liquid
|
|
|
28
28
|
def interpolate(name, vars)
|
|
29
29
|
name.gsub(/%\{(\w+)\}/) do
|
|
30
30
|
# raise TranslationError, "Undefined key #{$1} for interpolation in translation #{name}" unless vars[$1.to_sym]
|
|
31
|
-
|
|
31
|
+
vars[Regexp.last_match(1).to_sym].to_s
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
data/lib/liquid/locales/en.yml
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
block_tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: {% %{tag} %}{% end%{tag} %}"
|
|
6
6
|
assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"
|
|
7
7
|
capture: "Syntax Error in 'capture' - Valid syntax: capture [var]"
|
|
8
|
-
snippet: "Syntax Error in 'snippet' - Valid syntax: snippet [var]"
|
|
9
8
|
case: "Syntax Error in 'case' - Valid syntax: case [condition]"
|
|
10
9
|
case_invalid_when: "Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %}"
|
|
11
10
|
case_invalid_else: "Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) "
|
|
@@ -20,7 +19,6 @@
|
|
|
20
19
|
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
|
|
21
20
|
invalid_template_encoding: "Invalid template encoding"
|
|
22
21
|
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
|
23
|
-
render_invalid_template_name: "Syntax error in tag 'render' - Expected a string or identifier, found %{found}"
|
|
24
22
|
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
|
25
23
|
table_row_invalid_attribute: "Invalid attribute '%{attribute}' in tablerow loop. Valid attributes are cols, limit, offset, and range"
|
|
26
24
|
tag_never_closed: "'%{block_name}' tag was never closed"
|
|
@@ -31,6 +29,5 @@
|
|
|
31
29
|
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
|
|
32
30
|
argument:
|
|
33
31
|
include: "Argument error in tag 'include' - Illegal template name"
|
|
34
|
-
render: "Argument error in tag 'render' - Dynamically chosen templates are not allowed"
|
|
35
32
|
disabled:
|
|
36
33
|
tag: "usage is not allowed in this context"
|
data/lib/liquid/parse_context.rb
CHANGED
|
@@ -55,15 +55,15 @@ module Liquid
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def parse_expression(markup, safe: false)
|
|
58
|
-
if !safe && @error_mode == :
|
|
58
|
+
if !safe && @error_mode == :strict2
|
|
59
59
|
# parse_expression is a widely used API. To maintain backward
|
|
60
|
-
# compatibility while raising awareness about
|
|
60
|
+
# compatibility while raising awareness about strict2 parser standards,
|
|
61
61
|
# the safe flag supports API users make a deliberate decision.
|
|
62
62
|
#
|
|
63
|
-
# In
|
|
63
|
+
# In strict2 mode, markup MUST come from a string returned by the parser
|
|
64
64
|
# (e.g., parser.expression). We're not calling the parser here to
|
|
65
65
|
# prevent redundant parser overhead.
|
|
66
|
-
raise Liquid::InternalError, "unsafe parse_expression cannot be used in
|
|
66
|
+
raise Liquid::InternalError, "unsafe parse_expression cannot be used in strict2 mode"
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
Expression.parse(markup, @string_scanner, @expression_cache)
|
|
@@ -7,16 +7,19 @@ module Liquid
|
|
|
7
7
|
# It's basically doing the same thing the {#parse_with_selected_parser},
|
|
8
8
|
# except this will try the strict parser regardless of the error mode,
|
|
9
9
|
# and fall back to the lax parser if the error mode is lax or warn,
|
|
10
|
-
# except when in
|
|
10
|
+
# except when in strict2 mode where it uses the strict2 parser.
|
|
11
11
|
#
|
|
12
12
|
# @deprecated Use {#parse_with_selected_parser} instead.
|
|
13
13
|
def strict_parse_with_error_mode_fallback(markup)
|
|
14
|
-
return
|
|
14
|
+
return strict2_parse_with_error_context(markup) if strict2_mode?
|
|
15
15
|
|
|
16
16
|
strict_parse_with_error_context(markup)
|
|
17
17
|
rescue SyntaxError => e
|
|
18
18
|
case parse_context.error_mode
|
|
19
19
|
when :rigid
|
|
20
|
+
rigid_warn
|
|
21
|
+
raise
|
|
22
|
+
when :strict2
|
|
20
23
|
raise
|
|
21
24
|
when :strict
|
|
22
25
|
raise
|
|
@@ -28,12 +31,13 @@ module Liquid
|
|
|
28
31
|
|
|
29
32
|
def parse_with_selected_parser(markup)
|
|
30
33
|
case parse_context.error_mode
|
|
31
|
-
when :rigid
|
|
32
|
-
when :
|
|
33
|
-
when :
|
|
34
|
+
when :rigid then rigid_warn && strict2_parse_with_error_context(markup)
|
|
35
|
+
when :strict2 then strict2_parse_with_error_context(markup)
|
|
36
|
+
when :strict then strict_parse_with_error_context(markup)
|
|
37
|
+
when :lax then lax_parse(markup)
|
|
34
38
|
when :warn
|
|
35
39
|
begin
|
|
36
|
-
|
|
40
|
+
strict2_parse_with_error_context(markup)
|
|
37
41
|
rescue SyntaxError => e
|
|
38
42
|
parse_context.warnings << e
|
|
39
43
|
lax_parse(markup)
|
|
@@ -41,14 +45,18 @@ module Liquid
|
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
47
|
|
|
44
|
-
def
|
|
45
|
-
parse_context.error_mode == :rigid
|
|
48
|
+
def strict2_mode?
|
|
49
|
+
parse_context.error_mode == :strict2 || parse_context.error_mode == :rigid
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
private
|
|
49
53
|
|
|
50
|
-
def
|
|
51
|
-
|
|
54
|
+
def rigid_warn
|
|
55
|
+
Deprecations.warn(':rigid', ':strict2')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def strict2_parse_with_error_context(markup)
|
|
59
|
+
strict2_parse(markup)
|
|
52
60
|
rescue SyntaxError => e
|
|
53
61
|
e.line_number = line_number
|
|
54
62
|
e.markup_context = markup_context(markup)
|
|
@@ -2,24 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
module Liquid
|
|
4
4
|
class ResourceLimits
|
|
5
|
-
attr_accessor :render_length_limit,
|
|
6
|
-
|
|
5
|
+
attr_accessor :render_length_limit,
|
|
6
|
+
:render_score_limit,
|
|
7
|
+
:assign_score_limit,
|
|
8
|
+
:cumulative_render_score_limit,
|
|
9
|
+
:cumulative_assign_score_limit
|
|
10
|
+
attr_reader :render_score,
|
|
11
|
+
:assign_score,
|
|
12
|
+
:cumulative_render_score,
|
|
13
|
+
:cumulative_assign_score
|
|
7
14
|
|
|
8
15
|
def initialize(limits)
|
|
9
|
-
@render_length_limit
|
|
10
|
-
@render_score_limit
|
|
11
|
-
@assign_score_limit
|
|
16
|
+
@render_length_limit = limits[:render_length_limit]
|
|
17
|
+
@render_score_limit = limits[:render_score_limit]
|
|
18
|
+
@assign_score_limit = limits[:assign_score_limit]
|
|
19
|
+
@cumulative_render_score_limit = limits[:cumulative_render_score_limit]
|
|
20
|
+
@cumulative_assign_score_limit = limits[:cumulative_assign_score_limit]
|
|
21
|
+
@cumulative_render_score = 0
|
|
22
|
+
@cumulative_assign_score = 0
|
|
12
23
|
reset
|
|
13
24
|
end
|
|
14
25
|
|
|
15
26
|
def increment_render_score(amount)
|
|
16
27
|
@render_score += amount
|
|
28
|
+
@cumulative_render_score += amount
|
|
17
29
|
raise_limits_reached if @render_score_limit && @render_score > @render_score_limit
|
|
30
|
+
raise_limits_reached if @cumulative_render_score_limit && @cumulative_render_score > @cumulative_render_score_limit
|
|
18
31
|
end
|
|
19
32
|
|
|
20
33
|
def increment_assign_score(amount)
|
|
21
34
|
@assign_score += amount
|
|
35
|
+
@cumulative_assign_score += amount
|
|
22
36
|
raise_limits_reached if @assign_score_limit && @assign_score > @assign_score_limit
|
|
37
|
+
raise_limits_reached if @cumulative_assign_score_limit && @cumulative_assign_score > @cumulative_assign_score_limit
|
|
23
38
|
end
|
|
24
39
|
|
|
25
40
|
# update either render_length or assign_score based on whether or not the writes are captured
|
|
@@ -47,6 +62,8 @@ module Liquid
|
|
|
47
62
|
@reached_limit = false
|
|
48
63
|
@last_capture_length = nil
|
|
49
64
|
@render_score = @assign_score = 0
|
|
65
|
+
raise_limits_reached if @cumulative_render_score_limit && @cumulative_render_score > @cumulative_render_score_limit
|
|
66
|
+
raise_limits_reached if @cumulative_assign_score_limit && @cumulative_assign_score > @cumulative_assign_score_limit
|
|
50
67
|
end
|
|
51
68
|
|
|
52
69
|
def with_capture
|
|
@@ -293,6 +293,19 @@ module Liquid
|
|
|
293
293
|
input.split(pattern)
|
|
294
294
|
end
|
|
295
295
|
|
|
296
|
+
# @liquid_public_docs
|
|
297
|
+
# @liquid_type filter
|
|
298
|
+
# @liquid_category string
|
|
299
|
+
# @liquid_summary
|
|
300
|
+
# Removes leading and trailing whitespace and collapses consecutive whitespace to a single space.
|
|
301
|
+
# @liquid_syntax string | squish
|
|
302
|
+
# @liquid_return [string]
|
|
303
|
+
def squish(input)
|
|
304
|
+
return if input.nil?
|
|
305
|
+
|
|
306
|
+
Utils.to_s(input).strip.gsub(/\s+/, ' ')
|
|
307
|
+
end
|
|
308
|
+
|
|
296
309
|
# @liquid_public_docs
|
|
297
310
|
# @liquid_type filter
|
|
298
311
|
# @liquid_category string
|
|
@@ -768,6 +781,8 @@ module Liquid
|
|
|
768
781
|
# @liquid_syntax array | first
|
|
769
782
|
# @liquid_return [untyped]
|
|
770
783
|
def first(array)
|
|
784
|
+
# ActiveSupport returns "" for empty strings, not nil
|
|
785
|
+
return array[0] || "" if array.is_a?(String)
|
|
771
786
|
array.first if array.respond_to?(:first)
|
|
772
787
|
end
|
|
773
788
|
|
|
@@ -779,6 +794,8 @@ module Liquid
|
|
|
779
794
|
# @liquid_syntax array | last
|
|
780
795
|
# @liquid_return [untyped]
|
|
781
796
|
def last(array)
|
|
797
|
+
# ActiveSupport returns "" for empty strings, not nil
|
|
798
|
+
return array[-1] || "" if array.is_a?(String)
|
|
782
799
|
array.last if array.respond_to?(:last)
|
|
783
800
|
end
|
|
784
801
|
|
data/lib/liquid/tags/case.rb
CHANGED
|
@@ -86,7 +86,7 @@ module Liquid
|
|
|
86
86
|
|
|
87
87
|
private
|
|
88
88
|
|
|
89
|
-
def
|
|
89
|
+
def strict2_parse(markup)
|
|
90
90
|
parser = @parse_context.new_parser(markup)
|
|
91
91
|
@left = safe_parse_expression(parser)
|
|
92
92
|
parser.consume(:end_of_string)
|
|
@@ -107,18 +107,18 @@ module Liquid
|
|
|
107
107
|
def record_when_condition(markup)
|
|
108
108
|
body = new_body
|
|
109
109
|
|
|
110
|
-
if
|
|
111
|
-
|
|
110
|
+
if strict2_mode?
|
|
111
|
+
parse_strict2_when(markup, body)
|
|
112
112
|
else
|
|
113
113
|
parse_lax_when(markup, body)
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
-
def
|
|
117
|
+
def parse_strict2_when(markup, body)
|
|
118
118
|
parser = @parse_context.new_parser(markup)
|
|
119
119
|
|
|
120
120
|
loop do
|
|
121
|
-
expr =
|
|
121
|
+
expr = Condition.parse_expression(parse_context, parser.expression, safe: true)
|
|
122
122
|
block = Condition.new(@left, '==', expr)
|
|
123
123
|
block.attach(body)
|
|
124
124
|
@blocks << block
|
data/lib/liquid/tags/cycle.rb
CHANGED
data/lib/liquid/tags/for.rb
CHANGED
data/lib/liquid/tags/if.rb
CHANGED
data/lib/liquid/tags/include.rb
CHANGED
data/lib/liquid/tags/render.rb
CHANGED
|
@@ -27,7 +27,7 @@ module Liquid
|
|
|
27
27
|
# @liquid_syntax_keyword filename The name of the snippet to render, without the `.liquid` extension.
|
|
28
28
|
class Render < Tag
|
|
29
29
|
FOR = 'for'
|
|
30
|
-
SYNTAX = /(#{QuotedString}
|
|
30
|
+
SYNTAX = /(#{QuotedString}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
|
|
31
31
|
|
|
32
32
|
disable_tags "include"
|
|
33
33
|
|
|
@@ -47,23 +47,21 @@ module Liquid
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def render_tag(context, output)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
raise ::ArgumentError
|
|
62
|
-
end
|
|
50
|
+
# The expression should be a String literal, which parses to a String object
|
|
51
|
+
template_name = @template_name_expr
|
|
52
|
+
raise ::ArgumentError unless template_name.is_a?(String)
|
|
53
|
+
|
|
54
|
+
partial = PartialCache.load(
|
|
55
|
+
template_name,
|
|
56
|
+
context: context,
|
|
57
|
+
parse_context: parse_context,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
context_variable_name = @alias_name || template_name.split('/').last
|
|
63
61
|
|
|
64
62
|
render_partial_func = ->(var, forloop) {
|
|
65
63
|
inner_context = context.new_isolated_subcontext
|
|
66
|
-
inner_context.template_name =
|
|
64
|
+
inner_context.template_name = partial.name
|
|
67
65
|
inner_context.partial = true
|
|
68
66
|
inner_context['forloop'] = forloop if forloop
|
|
69
67
|
|
|
@@ -87,10 +85,10 @@ module Liquid
|
|
|
87
85
|
end
|
|
88
86
|
|
|
89
87
|
# render (string) (with|for expression)? (as id)? (key: value)*
|
|
90
|
-
def
|
|
88
|
+
def strict2_parse(markup)
|
|
91
89
|
p = @parse_context.new_parser(markup)
|
|
92
90
|
|
|
93
|
-
@template_name_expr = parse_expression(
|
|
91
|
+
@template_name_expr = parse_expression(strict2_template_name(p), safe: true)
|
|
94
92
|
with_or_for = p.id?("for") || p.id?("with")
|
|
95
93
|
@variable_name_expr = safe_parse_expression(p) if with_or_for
|
|
96
94
|
@alias_name = p.consume(:id) if p.id?("as")
|
|
@@ -103,18 +101,14 @@ module Liquid
|
|
|
103
101
|
key = p.consume
|
|
104
102
|
p.consume(:colon)
|
|
105
103
|
@attributes[key] = safe_parse_expression(p)
|
|
106
|
-
p.consume?(:comma)
|
|
104
|
+
p.consume?(:comma)
|
|
107
105
|
end
|
|
108
106
|
|
|
109
107
|
p.consume(:end_of_string)
|
|
110
108
|
end
|
|
111
109
|
|
|
112
|
-
def
|
|
113
|
-
|
|
114
|
-
return p.consume(:id) if p.look(:id)
|
|
115
|
-
|
|
116
|
-
found = p.consume || "nothing"
|
|
117
|
-
raise SyntaxError, options[:locale].t("errors.syntax.render_invalid_template_name", found: found)
|
|
110
|
+
def strict2_template_name(p)
|
|
111
|
+
p.consume(:string)
|
|
118
112
|
end
|
|
119
113
|
|
|
120
114
|
def strict_parse(markup)
|
data/lib/liquid/tags.rb
CHANGED
|
@@ -20,7 +20,6 @@ require_relative "tags/raw"
|
|
|
20
20
|
require_relative "tags/render"
|
|
21
21
|
require_relative "tags/cycle"
|
|
22
22
|
require_relative "tags/doc"
|
|
23
|
-
require_relative "tags/snippet"
|
|
24
23
|
|
|
25
24
|
module Liquid
|
|
26
25
|
module Tags
|
|
@@ -45,7 +44,6 @@ module Liquid
|
|
|
45
44
|
'echo' => Echo,
|
|
46
45
|
'tablerow' => TableRow,
|
|
47
46
|
'doc' => Doc,
|
|
48
|
-
'snippet' => Snippet,
|
|
49
47
|
}.freeze
|
|
50
48
|
end
|
|
51
49
|
end
|
data/lib/liquid/template.rb
CHANGED
|
@@ -25,7 +25,7 @@ module Liquid
|
|
|
25
25
|
# :lax acts like liquid 2.5 and silently ignores malformed tags in most cases.
|
|
26
26
|
# :warn is the default and will give deprecation warnings when invalid syntax is used.
|
|
27
27
|
# :strict enforces correct syntax for most tags
|
|
28
|
-
# :
|
|
28
|
+
# :strict2 enforces correct syntax for all tags
|
|
29
29
|
def error_mode=(mode)
|
|
30
30
|
Deprecations.warn("Template.error_mode=", "Environment#error_mode=")
|
|
31
31
|
Environment.default.error_mode = mode
|
data/lib/liquid/tokenizer.rb
CHANGED
|
@@ -117,7 +117,7 @@ module Liquid
|
|
|
117
117
|
byte_a = byte_b = @ss.scan_byte
|
|
118
118
|
|
|
119
119
|
while byte_b
|
|
120
|
-
byte_a = @ss.scan_byte while byte_a &&
|
|
120
|
+
byte_a = @ss.scan_byte while byte_a && byte_a != CLOSE_CURLEY && byte_a != OPEN_CURLEY
|
|
121
121
|
|
|
122
122
|
break unless byte_a
|
|
123
123
|
|
data/lib/liquid/utils.rb
CHANGED
|
@@ -69,7 +69,7 @@ module Liquid
|
|
|
69
69
|
return obj if obj.respond_to?(:strftime)
|
|
70
70
|
|
|
71
71
|
if obj.is_a?(String)
|
|
72
|
-
return
|
|
72
|
+
return if obj.empty?
|
|
73
73
|
obj = obj.downcase
|
|
74
74
|
end
|
|
75
75
|
|
|
@@ -95,6 +95,8 @@ module Liquid
|
|
|
95
95
|
|
|
96
96
|
def self.to_s(obj, seen = {})
|
|
97
97
|
case obj
|
|
98
|
+
when BigDecimal
|
|
99
|
+
obj.to_s("F")
|
|
98
100
|
when Hash
|
|
99
101
|
# If the custom hash implementation overrides `#to_s`, use their
|
|
100
102
|
# custom implementation. Otherwise we use Liquid's default
|
data/lib/liquid/variable.rb
CHANGED
|
@@ -74,14 +74,14 @@ module Liquid
|
|
|
74
74
|
p.consume(:end_of_string)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
def
|
|
77
|
+
def strict2_parse(markup)
|
|
78
78
|
@filters = []
|
|
79
79
|
p = @parse_context.new_parser(markup)
|
|
80
80
|
|
|
81
81
|
return if p.look(:end_of_string)
|
|
82
82
|
|
|
83
83
|
@name = parse_context.safe_parse_expression(p)
|
|
84
|
-
@filters <<
|
|
84
|
+
@filters << strict2_parse_filter_expressions(p) while p.consume?(:pipe)
|
|
85
85
|
p.consume(:end_of_string)
|
|
86
86
|
end
|
|
87
87
|
|
|
@@ -156,7 +156,7 @@ module Liquid
|
|
|
156
156
|
# argument = (positional_argument | keyword_argument)
|
|
157
157
|
# positional_argument = expression
|
|
158
158
|
# keyword_argument = id ":" expression
|
|
159
|
-
def
|
|
159
|
+
def strict2_parse_filter_expressions(p)
|
|
160
160
|
filtername = p.consume(:id)
|
|
161
161
|
filter_args = []
|
|
162
162
|
keyword_args = {}
|
|
@@ -70,6 +70,11 @@ module Liquid
|
|
|
70
70
|
elsif lookup_command?(i) && object.respond_to?(key)
|
|
71
71
|
object = object.send(key).to_liquid
|
|
72
72
|
|
|
73
|
+
# Handle string first/last like ActiveSupport does (returns first/last character)
|
|
74
|
+
# ActiveSupport returns "" for empty strings, not nil
|
|
75
|
+
elsif lookup_command?(i) && object.is_a?(String) && (key == "first" || key == "last")
|
|
76
|
+
object = key == "first" ? (object[0] || "") : (object[-1] || "")
|
|
77
|
+
|
|
73
78
|
# No key was present with the desired value and it wasn't one of the directly supported
|
|
74
79
|
# keywords either. The only thing we got left is to return nil or
|
|
75
80
|
# raise an exception if `strict_variables` option is set to true
|
data/lib/liquid/version.rb
CHANGED
data/lib/liquid.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: liquid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tobias Lütke
|
|
@@ -105,7 +105,6 @@ files:
|
|
|
105
105
|
- lib/liquid/range_lookup.rb
|
|
106
106
|
- lib/liquid/registers.rb
|
|
107
107
|
- lib/liquid/resource_limits.rb
|
|
108
|
-
- lib/liquid/snippet_drop.rb
|
|
109
108
|
- lib/liquid/standardfilters.rb
|
|
110
109
|
- lib/liquid/strainer_template.rb
|
|
111
110
|
- lib/liquid/tablerowloop_drop.rb
|
|
@@ -131,7 +130,6 @@ files:
|
|
|
131
130
|
- lib/liquid/tags/inline_comment.rb
|
|
132
131
|
- lib/liquid/tags/raw.rb
|
|
133
132
|
- lib/liquid/tags/render.rb
|
|
134
|
-
- lib/liquid/tags/snippet.rb
|
|
135
133
|
- lib/liquid/tags/table_row.rb
|
|
136
134
|
- lib/liquid/tags/unless.rb
|
|
137
135
|
- lib/liquid/template.rb
|
|
@@ -161,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
161
159
|
- !ruby/object:Gem::Version
|
|
162
160
|
version: 1.3.7
|
|
163
161
|
requirements: []
|
|
164
|
-
rubygems_version:
|
|
162
|
+
rubygems_version: 4.0.8
|
|
165
163
|
specification_version: 4
|
|
166
164
|
summary: A secure, non-evaling end user template engine with aesthetic markup.
|
|
167
165
|
test_files: []
|
data/lib/liquid/snippet_drop.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Liquid
|
|
4
|
-
class SnippetDrop < Drop
|
|
5
|
-
attr_reader :body, :name, :filename
|
|
6
|
-
|
|
7
|
-
def initialize(body, name, filename)
|
|
8
|
-
super()
|
|
9
|
-
@body = body
|
|
10
|
-
@name = name
|
|
11
|
-
@filename = filename
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def to_partial
|
|
15
|
-
@body
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def to_s
|
|
19
|
-
'SnippetDrop'
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
data/lib/liquid/tags/snippet.rb
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Liquid
|
|
4
|
-
# @liquid_public_docs
|
|
5
|
-
# @liquid_type tag
|
|
6
|
-
# @liquid_category variable
|
|
7
|
-
# @liquid_name snippet
|
|
8
|
-
# @liquid_summary
|
|
9
|
-
# Creates a new inline snippet.
|
|
10
|
-
# @liquid_description
|
|
11
|
-
# You can create inline snippets to make your Liquid code more modular.
|
|
12
|
-
# @liquid_syntax
|
|
13
|
-
# {% snippet snippet_name %}
|
|
14
|
-
# value
|
|
15
|
-
# {% endsnippet %}
|
|
16
|
-
class Snippet < Block
|
|
17
|
-
def initialize(tag_name, markup, options)
|
|
18
|
-
super
|
|
19
|
-
p = @parse_context.new_parser(markup)
|
|
20
|
-
if p.look(:id)
|
|
21
|
-
@to = p.consume(:id)
|
|
22
|
-
p.consume(:end_of_string)
|
|
23
|
-
else
|
|
24
|
-
raise SyntaxError, options[:locale].t("errors.syntax.snippet")
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def render_to_output_buffer(context, output)
|
|
29
|
-
snippet_drop = SnippetDrop.new(@body, @to, context.template_name)
|
|
30
|
-
context.scopes.last[@to] = snippet_drop
|
|
31
|
-
context.resource_limits.increment_assign_score(assign_score_of(snippet_drop))
|
|
32
|
-
output
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def blank?
|
|
36
|
-
true
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
def assign_score_of(snippet_drop)
|
|
42
|
-
snippet_drop.body.nodelist.sum { |node| node.to_s.bytesize }
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|