liquid 5.7.1 → 5.8.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 +18 -6
- data/lib/liquid/lexer.rb +6 -0
- data/lib/liquid/locales/en.yml +2 -0
- data/lib/liquid/standardfilters.rb +9 -34
- data/lib/liquid/tags/doc.rb +70 -0
- data/lib/liquid/tags.rb +2 -0
- data/lib/liquid/tokenizer.rb +6 -0
- data/lib/liquid/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d27b4c9417e479c5eec775f4ec1e5dd6165a2fb5fe76a8b769b31bc5acaff334
|
|
4
|
+
data.tar.gz: 77aef473425cf804dd4dfe1a17f00a424e70e30143952c9670c20d947fa038aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40f39337b8767db07e12beb2aa2a155a3bfb975752e02a09626b7fe3d53ef73c0c79252f29f2cb4a6edc63b8f0afff06d0df663d9a74d27a1f9507efd5db4a2c
|
|
7
|
+
data.tar.gz: 350ee158bdd4dabfb8781c937ca6426ee06cbaaedaffa469aa324fe717d7b7fbbf1f7a82aebd61a0bd9f96bc0ae4a94e887115385d1ca1f9c76aa2613ef88881
|
data/History.md
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
# Liquid Change Log
|
|
2
2
|
|
|
3
|
-
## 5.8.
|
|
3
|
+
## 5.8.1 (unreleased)
|
|
4
4
|
|
|
5
|
-
## 5.
|
|
5
|
+
## 5.8.0
|
|
6
6
|
|
|
7
|
-
*
|
|
8
|
-
|
|
7
|
+
* Introduce the new `{% doc %}` tag [Guilherme Carreiro]
|
|
8
|
+
|
|
9
|
+
## 5.7.3
|
|
10
|
+
|
|
11
|
+
* Raise Liquid::SyntaxError when parsing invalidly encoded strings [Chris AtLee]
|
|
12
|
+
|
|
13
|
+
## 5.7.2 2025-01-31
|
|
14
|
+
|
|
15
|
+
* Fix array filters to not support nested properties [Guilherme Carreiro]
|
|
16
|
+
|
|
17
|
+
## 5.7.1 2025-01-24
|
|
18
|
+
|
|
19
|
+
* Fix the `find` and `find_index`filters to return `nil` when filtering empty arrays [Guilherme Carreiro]
|
|
20
|
+
* Fix the `has` filter to return `false` when filtering empty arrays [Guilherme Carreiro]
|
|
9
21
|
|
|
10
22
|
## 5.7.0 2025-01-16
|
|
11
23
|
|
|
12
24
|
### Features
|
|
13
25
|
|
|
14
|
-
* Add `find`, `find_index`, `has`, and `reject` filters to arrays
|
|
15
|
-
* Compatibility with Ruby 3.4
|
|
26
|
+
* Add `find`, `find_index`, `has`, and `reject` filters to arrays [Guilherme Carreiro]
|
|
27
|
+
* Compatibility with Ruby 3.4 [Ian Ker-Seymer]
|
|
16
28
|
|
|
17
29
|
## 5.6.4 2025-01-14
|
|
18
30
|
|
data/lib/liquid/lexer.rb
CHANGED
|
@@ -161,6 +161,12 @@ module Liquid
|
|
|
161
161
|
end
|
|
162
162
|
# rubocop:enable Metrics/BlockNesting
|
|
163
163
|
output << EOS
|
|
164
|
+
rescue ::ArgumentError => e
|
|
165
|
+
if e.message == "invalid byte sequence in #{ss.string.encoding}"
|
|
166
|
+
raise SyntaxError, "Invalid byte sequence in #{ss.string.encoding}"
|
|
167
|
+
else
|
|
168
|
+
raise
|
|
169
|
+
end
|
|
164
170
|
end
|
|
165
171
|
|
|
166
172
|
def raise_syntax_error(start_pos, ss)
|
data/lib/liquid/locales/en.yml
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
errors:
|
|
3
3
|
syntax:
|
|
4
4
|
tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: %{tag}"
|
|
5
|
+
block_tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: {% %{tag} %}{% end%{tag} %}"
|
|
5
6
|
assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"
|
|
6
7
|
capture: "Syntax Error in 'capture' - Valid syntax: capture [var]"
|
|
7
8
|
case: "Syntax Error in 'case' - Valid syntax: case [condition]"
|
|
8
9
|
case_invalid_when: "Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %}"
|
|
9
10
|
case_invalid_else: "Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) "
|
|
10
11
|
cycle: "Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]"
|
|
12
|
+
doc_invalid_nested: "Syntax Error in 'doc' - Nested doc tags are not allowed"
|
|
11
13
|
for: "Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]"
|
|
12
14
|
for_invalid_in: "For loops require an 'in' clause"
|
|
13
15
|
for_invalid_attribute: "Invalid attribute in for loop. Valid attributes are limit and offset"
|
|
@@ -387,7 +387,7 @@ module Liquid
|
|
|
387
387
|
end
|
|
388
388
|
elsif ary.all? { |el| el.respond_to?(:[]) }
|
|
389
389
|
begin
|
|
390
|
-
ary.sort { |a, b| nil_safe_compare(
|
|
390
|
+
ary.sort { |a, b| nil_safe_compare(a[property], b[property]) }
|
|
391
391
|
rescue TypeError
|
|
392
392
|
raise_property_error(property)
|
|
393
393
|
end
|
|
@@ -416,7 +416,7 @@ module Liquid
|
|
|
416
416
|
end
|
|
417
417
|
elsif ary.all? { |el| el.respond_to?(:[]) }
|
|
418
418
|
begin
|
|
419
|
-
ary.sort { |a, b| nil_safe_casecmp(
|
|
419
|
+
ary.sort { |a, b| nil_safe_casecmp(a[property], b[property]) }
|
|
420
420
|
rescue TypeError
|
|
421
421
|
raise_property_error(property)
|
|
422
422
|
end
|
|
@@ -456,7 +456,7 @@ module Liquid
|
|
|
456
456
|
# Tests if any item in an array has a specific property value.
|
|
457
457
|
# @liquid_description
|
|
458
458
|
# This requires you to provide both the property name and the associated value.
|
|
459
|
-
# @liquid_syntax array |
|
|
459
|
+
# @liquid_syntax array | has: string, string
|
|
460
460
|
# @liquid_return [boolean]
|
|
461
461
|
def has(input, property, target_value = nil)
|
|
462
462
|
filter_array(input, property, target_value, false) { |ary, &block| ary.any?(&block) }
|
|
@@ -504,7 +504,7 @@ module Liquid
|
|
|
504
504
|
[]
|
|
505
505
|
else
|
|
506
506
|
ary.uniq do |item|
|
|
507
|
-
|
|
507
|
+
item[property]
|
|
508
508
|
rescue TypeError
|
|
509
509
|
raise_property_error(property)
|
|
510
510
|
rescue NoMethodError
|
|
@@ -540,7 +540,7 @@ module Liquid
|
|
|
540
540
|
if property == "to_liquid"
|
|
541
541
|
e
|
|
542
542
|
elsif e.respond_to?(:[])
|
|
543
|
-
r =
|
|
543
|
+
r = e[property]
|
|
544
544
|
r.is_a?(Proc) ? r.call : r
|
|
545
545
|
end
|
|
546
546
|
end
|
|
@@ -564,7 +564,7 @@ module Liquid
|
|
|
564
564
|
[]
|
|
565
565
|
else
|
|
566
566
|
ary.reject do |item|
|
|
567
|
-
|
|
567
|
+
item[property].nil?
|
|
568
568
|
rescue TypeError
|
|
569
569
|
raise_property_error(property)
|
|
570
570
|
rescue NoMethodError
|
|
@@ -950,7 +950,7 @@ module Liquid
|
|
|
950
950
|
if property.nil?
|
|
951
951
|
item
|
|
952
952
|
elsif item.respond_to?(:[])
|
|
953
|
-
|
|
953
|
+
item[property]
|
|
954
954
|
else
|
|
955
955
|
0
|
|
956
956
|
end
|
|
@@ -976,9 +976,9 @@ module Liquid
|
|
|
976
976
|
|
|
977
977
|
block.call(ary) do |item|
|
|
978
978
|
if target_value.nil?
|
|
979
|
-
|
|
979
|
+
item[property]
|
|
980
980
|
else
|
|
981
|
-
|
|
981
|
+
item[property] == target_value
|
|
982
982
|
end
|
|
983
983
|
rescue TypeError
|
|
984
984
|
raise_property_error(property)
|
|
@@ -988,31 +988,6 @@ module Liquid
|
|
|
988
988
|
end
|
|
989
989
|
end
|
|
990
990
|
|
|
991
|
-
def fetch_property(drop, property_or_keys)
|
|
992
|
-
##
|
|
993
|
-
# This keeps backward compatibility by supporting properties containing
|
|
994
|
-
# dots. This is valid in Liquid syntax and used in some runtimes, such as
|
|
995
|
-
# Shopify with metafields.
|
|
996
|
-
#
|
|
997
|
-
# Using this approach, properties like 'price.value' can be accessed in
|
|
998
|
-
# both of the following examples:
|
|
999
|
-
#
|
|
1000
|
-
# ```
|
|
1001
|
-
# [
|
|
1002
|
-
# { 'name' => 'Item 1', 'price.price' => 40000 },
|
|
1003
|
-
# { 'name' => 'Item 2', 'price' => { 'value' => 39900 } }
|
|
1004
|
-
# ]
|
|
1005
|
-
# ```
|
|
1006
|
-
value = drop[property_or_keys]
|
|
1007
|
-
|
|
1008
|
-
return value if !value.nil? || !property_or_keys.is_a?(String)
|
|
1009
|
-
|
|
1010
|
-
keys = property_or_keys.split('.')
|
|
1011
|
-
keys.reduce(drop) do |drop, key|
|
|
1012
|
-
drop.respond_to?(:[]) ? drop[key] : drop
|
|
1013
|
-
end
|
|
1014
|
-
end
|
|
1015
|
-
|
|
1016
991
|
def raise_property_error(property)
|
|
1017
992
|
raise Liquid::ArgumentError, "cannot select the property '#{property}'"
|
|
1018
993
|
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Liquid
|
|
4
|
+
# @liquid_public_docs
|
|
5
|
+
# @liquid_type tag
|
|
6
|
+
# @liquid_category syntax
|
|
7
|
+
# @liquid_name doc
|
|
8
|
+
# @liquid_summary
|
|
9
|
+
# Documents template elements with annotations.
|
|
10
|
+
# @liquid_description
|
|
11
|
+
# The `doc` tag allows developers to include documentation within Liquid
|
|
12
|
+
# templates. Any content inside `doc` tags is not rendered or outputted.
|
|
13
|
+
# Liquid code inside will be parsed but not executed. This facilitates
|
|
14
|
+
# tooling support for features like code completion, linting, and inline
|
|
15
|
+
# documentation.
|
|
16
|
+
# @liquid_syntax
|
|
17
|
+
# {% doc %}
|
|
18
|
+
# Renders a message.
|
|
19
|
+
#
|
|
20
|
+
# @param {string} foo - A foo value.
|
|
21
|
+
# @param {string} [bar] - An optional bar value.
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# {% render 'message', foo: 'Hello', bar: 'World' %}
|
|
25
|
+
# {% enddoc %}
|
|
26
|
+
# {{ foo }}, {{ bar }}!
|
|
27
|
+
class Doc < Block
|
|
28
|
+
NO_UNEXPECTED_ARGS = /\A\s*\z/
|
|
29
|
+
|
|
30
|
+
def initialize(tag_name, markup, parse_context)
|
|
31
|
+
super
|
|
32
|
+
ensure_valid_markup(tag_name, markup, parse_context)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def parse(tokens)
|
|
36
|
+
while (token = tokens.shift)
|
|
37
|
+
tag_name = token =~ BlockBody::FullTokenPossiblyInvalid && Regexp.last_match(2)
|
|
38
|
+
|
|
39
|
+
raise_nested_doc_error if tag_name == @tag_name
|
|
40
|
+
|
|
41
|
+
if tag_name == block_delimiter
|
|
42
|
+
parse_context.trim_whitespace = (token[-3] == WhitespaceControl)
|
|
43
|
+
return
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
raise_tag_never_closed(block_name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def render_to_output_buffer(_context, output)
|
|
51
|
+
output
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def blank?
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def ensure_valid_markup(tag_name, markup, parse_context)
|
|
61
|
+
unless NO_UNEXPECTED_ARGS.match?(markup)
|
|
62
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.block_tag_unexpected_args", tag: tag_name)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def raise_nested_doc_error
|
|
67
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.doc_invalid_nested")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/liquid/tags.rb
CHANGED
|
@@ -19,6 +19,7 @@ require_relative "tags/comment"
|
|
|
19
19
|
require_relative "tags/raw"
|
|
20
20
|
require_relative "tags/render"
|
|
21
21
|
require_relative "tags/cycle"
|
|
22
|
+
require_relative "tags/doc"
|
|
22
23
|
|
|
23
24
|
module Liquid
|
|
24
25
|
module Tags
|
|
@@ -42,6 +43,7 @@ module Liquid
|
|
|
42
43
|
'if' => If,
|
|
43
44
|
'echo' => Echo,
|
|
44
45
|
'tablerow' => TableRow,
|
|
46
|
+
'doc' => Doc,
|
|
45
47
|
}.freeze
|
|
46
48
|
end
|
|
47
49
|
end
|
data/lib/liquid/tokenizer.rb
CHANGED
|
@@ -103,6 +103,12 @@ module Liquid
|
|
|
103
103
|
|
|
104
104
|
pos = @ss.pos -= 2
|
|
105
105
|
@source.byteslice(start, pos - start)
|
|
106
|
+
rescue ::ArgumentError => e
|
|
107
|
+
if e.message == "invalid byte sequence in #{@ss.string.encoding}"
|
|
108
|
+
raise SyntaxError, "Invalid byte sequence in #{@ss.string.encoding}"
|
|
109
|
+
else
|
|
110
|
+
raise
|
|
111
|
+
end
|
|
106
112
|
end
|
|
107
113
|
|
|
108
114
|
def next_variable_token
|
data/lib/liquid/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: liquid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tobias Lütke
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2025-
|
|
10
|
+
date: 2025-02-25 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: strscan
|
|
@@ -120,6 +120,7 @@ files:
|
|
|
120
120
|
- lib/liquid/tags/continue.rb
|
|
121
121
|
- lib/liquid/tags/cycle.rb
|
|
122
122
|
- lib/liquid/tags/decrement.rb
|
|
123
|
+
- lib/liquid/tags/doc.rb
|
|
123
124
|
- lib/liquid/tags/echo.rb
|
|
124
125
|
- lib/liquid/tags/for.rb
|
|
125
126
|
- lib/liquid/tags/if.rb
|
|
@@ -158,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
158
159
|
- !ruby/object:Gem::Version
|
|
159
160
|
version: 1.3.7
|
|
160
161
|
requirements: []
|
|
161
|
-
rubygems_version: 3.6.
|
|
162
|
+
rubygems_version: 3.6.3
|
|
162
163
|
specification_version: 4
|
|
163
164
|
summary: A secure, non-evaling end user template engine with aesthetic markup.
|
|
164
165
|
test_files: []
|