liquid 5.1.0 → 5.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +35 -0
- data/README.md +4 -4
- data/lib/liquid/block_body.rb +6 -6
- data/lib/liquid/condition.rb +7 -1
- data/lib/liquid/context.rb +6 -2
- data/lib/liquid/expression.rb +11 -10
- data/lib/liquid/forloop_drop.rb +44 -1
- data/lib/liquid/locales/en.yml +6 -5
- data/lib/liquid/partial_cache.rb +3 -3
- data/lib/liquid/registers.rb +51 -0
- data/lib/liquid/standardfilters.rb +463 -75
- data/lib/liquid/strainer_factory.rb +15 -10
- data/lib/liquid/strainer_template.rb +9 -0
- data/lib/liquid/tablerowloop_drop.rb +58 -1
- data/lib/liquid/tags/assign.rb +12 -8
- data/lib/liquid/tags/break.rb +8 -0
- data/lib/liquid/tags/capture.rb +13 -10
- data/lib/liquid/tags/case.rb +21 -0
- data/lib/liquid/tags/comment.rb +13 -0
- data/lib/liquid/tags/continue.rb +8 -9
- data/lib/liquid/tags/cycle.rb +12 -11
- data/lib/liquid/tags/decrement.rb +16 -17
- data/lib/liquid/tags/echo.rb +16 -9
- data/lib/liquid/tags/for.rb +22 -43
- data/lib/liquid/tags/if.rb +11 -9
- data/lib/liquid/tags/include.rb +15 -13
- data/lib/liquid/tags/increment.rb +16 -14
- data/lib/liquid/tags/inline_comment.rb +43 -0
- data/lib/liquid/tags/raw.rb +11 -0
- data/lib/liquid/tags/render.rb +29 -4
- data/lib/liquid/tags/table_row.rb +22 -0
- data/lib/liquid/tags/unless.rb +15 -4
- data/lib/liquid/template.rb +2 -3
- data/lib/liquid/variable.rb +4 -4
- data/lib/liquid/variable_lookup.rb +10 -7
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +4 -4
- metadata +7 -121
- data/lib/liquid/register.rb +0 -6
- data/lib/liquid/static_registers.rb +0 -44
- data/test/fixtures/en_locale.yml +0 -9
- data/test/integration/assign_test.rb +0 -117
- data/test/integration/blank_test.rb +0 -109
- data/test/integration/block_test.rb +0 -58
- data/test/integration/capture_test.rb +0 -58
- data/test/integration/context_test.rb +0 -636
- data/test/integration/document_test.rb +0 -21
- data/test/integration/drop_test.rb +0 -257
- data/test/integration/error_handling_test.rb +0 -272
- data/test/integration/expression_test.rb +0 -46
- data/test/integration/filter_test.rb +0 -189
- data/test/integration/hash_ordering_test.rb +0 -25
- data/test/integration/output_test.rb +0 -125
- data/test/integration/parsing_quirks_test.rb +0 -134
- data/test/integration/profiler_test.rb +0 -213
- data/test/integration/security_test.rb +0 -89
- data/test/integration/standard_filter_test.rb +0 -880
- data/test/integration/tag/disableable_test.rb +0 -59
- data/test/integration/tag_test.rb +0 -45
- data/test/integration/tags/break_tag_test.rb +0 -17
- data/test/integration/tags/continue_tag_test.rb +0 -17
- data/test/integration/tags/echo_test.rb +0 -13
- data/test/integration/tags/for_tag_test.rb +0 -466
- data/test/integration/tags/if_else_tag_test.rb +0 -190
- data/test/integration/tags/include_tag_test.rb +0 -269
- data/test/integration/tags/increment_tag_test.rb +0 -25
- data/test/integration/tags/liquid_tag_test.rb +0 -116
- data/test/integration/tags/raw_tag_test.rb +0 -34
- data/test/integration/tags/render_tag_test.rb +0 -213
- data/test/integration/tags/standard_tag_test.rb +0 -303
- data/test/integration/tags/statements_test.rb +0 -113
- data/test/integration/tags/table_row_test.rb +0 -66
- data/test/integration/tags/unless_else_tag_test.rb +0 -28
- data/test/integration/template_test.rb +0 -340
- data/test/integration/trim_mode_test.rb +0 -563
- data/test/integration/variable_test.rb +0 -138
- data/test/test_helper.rb +0 -207
- data/test/unit/block_unit_test.rb +0 -53
- data/test/unit/condition_unit_test.rb +0 -168
- data/test/unit/file_system_unit_test.rb +0 -37
- data/test/unit/i18n_unit_test.rb +0 -39
- data/test/unit/lexer_unit_test.rb +0 -53
- data/test/unit/parse_tree_visitor_test.rb +0 -261
- data/test/unit/parser_unit_test.rb +0 -84
- data/test/unit/partial_cache_unit_test.rb +0 -128
- data/test/unit/regexp_unit_test.rb +0 -46
- data/test/unit/static_registers_unit_test.rb +0 -156
- data/test/unit/strainer_factory_unit_test.rb +0 -100
- data/test/unit/strainer_template_unit_test.rb +0 -82
- data/test/unit/tag_unit_test.rb +0 -23
- data/test/unit/tags/case_tag_unit_test.rb +0 -12
- data/test/unit/tags/for_tag_unit_test.rb +0 -15
- data/test/unit/tags/if_tag_unit_test.rb +0 -10
- data/test/unit/template_factory_unit_test.rb +0 -12
- data/test/unit/template_unit_test.rb +0 -87
- data/test/unit/tokenizer_unit_test.rb +0 -62
- data/test/unit/variable_unit_test.rb +0 -164
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8408df245a1cc22ee1154fe5387e3e41eb3c740f7277e7d3736c1863d387e47
|
4
|
+
data.tar.gz: 64549a58828fd7e9e0eb7310cb4371e75e64a7c3249fe9ebd021039e3334bba1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29aaff16e3bc464712cdcac3aa205df943132198ef9568d46f4a123d327849f7ead7bd669a095eae0425581eb59ea08874ac38664bf9d8df00b0aa99917c7768
|
7
|
+
data.tar.gz: 9f6070c39733b7f4064f70676b1f886fc61070f3ba8921360b9c5fcdb09c217b3e58c3d59d8293b24b6c18e55899ed17552a2f867ea8eb95e7dee9a7deb29ae5
|
data/History.md
CHANGED
@@ -1,5 +1,40 @@
|
|
1
1
|
# Liquid Change Log
|
2
2
|
|
3
|
+
## 5.4.0 2022-07-29
|
4
|
+
|
5
|
+
### Breaking Changes
|
6
|
+
* Drop support for end-of-life Ruby versions (2.5 and 2.6) (#1578) [Andy Waite]
|
7
|
+
|
8
|
+
### Features
|
9
|
+
* Allow `#` to be used as an inline comment tag (#1498) [CP Clermont]
|
10
|
+
|
11
|
+
### Fixes
|
12
|
+
* `PartialCache` now shares snippet cache with subcontexts by default (#1553) [Chris AtLee]
|
13
|
+
* Hash registers no longer leak into subcontexts as static registers (#1564) [Chris AtLee]
|
14
|
+
* Fix `ParseTreeVisitor` for `with` variable expressions in `Render` tag (#1596) [CP Clermont]
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
* Liquid::Context#registers now always returns a Liquid::Registers object, though supports the most used Hash functions for compatibility (#1553)
|
18
|
+
|
19
|
+
## 5.3.0 2022-03-22
|
20
|
+
|
21
|
+
### Fixes
|
22
|
+
* StandardFilter: Fix missing @context on iterations (#1525) [Thierry Joyal]
|
23
|
+
* Fix warning about block and default value in `static_registers.rb` (#1531) [Peter Zhu]
|
24
|
+
|
25
|
+
### Deprecation
|
26
|
+
* Condition#evaluate to require mandatory context argument in Liquid 6.0.0 (#1527) [Thierry Joyal]
|
27
|
+
|
28
|
+
## 5.2.0 2022-03-01
|
29
|
+
|
30
|
+
### Features
|
31
|
+
* Add `remove_last`, and `replace_last` filters (#1422) [Anders Hagbard]
|
32
|
+
* Eagerly cache global filters (#1524) [Jean Boussier]
|
33
|
+
|
34
|
+
### Fixes
|
35
|
+
* Fix some internal errors in filters from invalid input (#1476) [Dylan Thacker-Smith]
|
36
|
+
* Allow dash in filter kwarg name for consistency with Liquid::C (#1518) [CP Clermont]
|
37
|
+
|
3
38
|
## 5.1.0 / 2021-09-09
|
4
39
|
|
5
40
|
### Features
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
* [Contributing guidelines](CONTRIBUTING.md)
|
7
7
|
* [Version history](History.md)
|
8
|
-
* [Liquid documentation from Shopify](
|
8
|
+
* [Liquid documentation from Shopify](https://shopify.dev/api/liquid)
|
9
9
|
* [Liquid Wiki at GitHub](https://github.com/Shopify/liquid/wiki)
|
10
10
|
* [Website](http://liquidmarkup.org/)
|
11
11
|
|
@@ -56,20 +56,20 @@ For standard use you can just pass it the content of a file and call render with
|
|
56
56
|
|
57
57
|
Setting the error mode of Liquid lets you specify how strictly you want your templates to be interpreted.
|
58
58
|
Normally the parser is very lax and will accept almost anything without error. Unfortunately this can make
|
59
|
-
it very hard to debug and can lead to unexpected behaviour.
|
59
|
+
it very hard to debug and can lead to unexpected behaviour.
|
60
60
|
|
61
61
|
Liquid also comes with a stricter parser that can be used when editing templates to give better error messages
|
62
62
|
when templates are invalid. You can enable this new parser like this:
|
63
63
|
|
64
64
|
```ruby
|
65
65
|
Liquid::Template.error_mode = :strict # Raises a SyntaxError when invalid syntax is used
|
66
|
-
Liquid::Template.error_mode = :warn # Adds errors to template.errors but continues as normal
|
66
|
+
Liquid::Template.error_mode = :warn # Adds strict errors to template.errors but continues as normal
|
67
67
|
Liquid::Template.error_mode = :lax # The default mode, accepts almost anything.
|
68
68
|
```
|
69
69
|
|
70
70
|
If you want to set the error mode only on specific templates you can pass `:error_mode` as an option to `parse`:
|
71
71
|
```ruby
|
72
|
-
Liquid::Template.parse(source, :
|
72
|
+
Liquid::Template.parse(source, error_mode: :strict)
|
73
73
|
```
|
74
74
|
This is useful for doing things like enabling strict mode only in the theme editor.
|
75
75
|
|
data/lib/liquid/block_body.rb
CHANGED
@@ -4,8 +4,8 @@ require 'English'
|
|
4
4
|
|
5
5
|
module Liquid
|
6
6
|
class BlockBody
|
7
|
-
LiquidTagToken = /\A\s*(
|
8
|
-
FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(
|
7
|
+
LiquidTagToken = /\A\s*(#{TagName})\s*(.*?)\z/o
|
8
|
+
FullToken = /\A#{TagStart}#{WhitespaceControl}?(\s*)(#{TagName})(\s*)(.*?)#{WhitespaceControl}?#{TagEnd}\z/om
|
9
9
|
ContentOfVariable = /\A#{VariableStart}#{WhitespaceControl}?(.*?)#{WhitespaceControl}?#{VariableEnd}\z/om
|
10
10
|
WhitespaceOrNothing = /\A\s*\z/
|
11
11
|
TAGSTART = "{%"
|
@@ -37,7 +37,7 @@ module Liquid
|
|
37
37
|
|
38
38
|
private def parse_for_liquid_tag(tokenizer, parse_context)
|
39
39
|
while (token = tokenizer.shift)
|
40
|
-
unless token.empty? || token
|
40
|
+
unless token.empty? || token.match?(WhitespaceOrNothing)
|
41
41
|
unless token =~ LiquidTagToken
|
42
42
|
# line isn't empty but didn't match tag syntax, yield and let the
|
43
43
|
# caller raise a syntax error
|
@@ -150,7 +150,7 @@ module Liquid
|
|
150
150
|
end
|
151
151
|
parse_context.trim_whitespace = false
|
152
152
|
@nodelist << token
|
153
|
-
@blank &&=
|
153
|
+
@blank &&= token.match?(WhitespaceOrNothing)
|
154
154
|
end
|
155
155
|
parse_context.line_number = tokenizer.line_number
|
156
156
|
end
|
@@ -231,8 +231,8 @@ module Liquid
|
|
231
231
|
end
|
232
232
|
|
233
233
|
def create_variable(token, parse_context)
|
234
|
-
token
|
235
|
-
markup =
|
234
|
+
if token =~ ContentOfVariable
|
235
|
+
markup = Regexp.last_match(1)
|
236
236
|
return Variable.new(markup, parse_context)
|
237
237
|
end
|
238
238
|
BlockBody.raise_missing_variable_terminator(token, parse_context)
|
data/lib/liquid/condition.rb
CHANGED
@@ -61,7 +61,7 @@ module Liquid
|
|
61
61
|
@child_condition = nil
|
62
62
|
end
|
63
63
|
|
64
|
-
def evaluate(context =
|
64
|
+
def evaluate(context = deprecated_default_context)
|
65
65
|
condition = self
|
66
66
|
result = nil
|
67
67
|
loop do
|
@@ -150,6 +150,12 @@ module Liquid
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
def deprecated_default_context
|
154
|
+
warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated" \
|
155
|
+
" and will be removed from Liquid 6.0.0.")
|
156
|
+
Context.new
|
157
|
+
end
|
158
|
+
|
153
159
|
class ParseTreeVisitor < Liquid::ParseTreeVisitor
|
154
160
|
def children
|
155
161
|
[
|
data/lib/liquid/context.rb
CHANGED
@@ -28,7 +28,7 @@ module Liquid
|
|
28
28
|
|
29
29
|
@static_environments = [static_environments].flat_map(&:freeze).freeze
|
30
30
|
@scopes = [(outer_scope || {})]
|
31
|
-
@registers = registers
|
31
|
+
@registers = registers.is_a?(Registers) ? registers : Registers.new(registers)
|
32
32
|
@errors = []
|
33
33
|
@partial = false
|
34
34
|
@strict_variables = false
|
@@ -39,6 +39,10 @@ module Liquid
|
|
39
39
|
@global_filter = nil
|
40
40
|
@disabled_tags = {}
|
41
41
|
|
42
|
+
@registers.static[:cached_partials] ||= {}
|
43
|
+
@registers.static[:file_system] ||= Liquid::Template.file_system
|
44
|
+
@registers.static[:template_factory] ||= Liquid::TemplateFactory.new
|
45
|
+
|
42
46
|
self.exception_renderer = Template.default_exception_renderer
|
43
47
|
if rethrow_errors
|
44
48
|
self.exception_renderer = Liquid::RAISE_EXCEPTION_LAMBDA
|
@@ -140,7 +144,7 @@ module Liquid
|
|
140
144
|
self.class.build(
|
141
145
|
resource_limits: resource_limits,
|
142
146
|
static_environments: static_environments,
|
143
|
-
registers:
|
147
|
+
registers: Registers.new(registers)
|
144
148
|
).tap do |subcontext|
|
145
149
|
subcontext.base_scope_depth = base_scope_depth + 1
|
146
150
|
subcontext.exception_renderer = exception_renderer
|
data/lib/liquid/expression.rb
CHANGED
@@ -10,21 +10,23 @@ module Liquid
|
|
10
10
|
'empty' => ''
|
11
11
|
}.freeze
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
INTEGERS_REGEX = /\A\s*(-?\d+)\s*\z/
|
16
|
-
FLOATS_REGEX = /\A\s*(-?\d[\d\.]+)\s*\z/
|
13
|
+
INTEGERS_REGEX = /\A(-?\d+)\z/
|
14
|
+
FLOATS_REGEX = /\A(-?\d[\d\.]+)\z/
|
17
15
|
|
18
16
|
# Use an atomic group (?>...) to avoid pathological backtracing from
|
19
17
|
# malicious input as described in https://github.com/Shopify/liquid/issues/1357
|
20
|
-
RANGES_REGEX = /\A\
|
18
|
+
RANGES_REGEX = /\A\(\s*(?>(\S+)\s*\.\.)\s*(\S+)\s*\)\z/
|
21
19
|
|
22
20
|
def self.parse(markup)
|
21
|
+
return nil unless markup
|
22
|
+
|
23
|
+
markup = markup.strip
|
24
|
+
if (markup.start_with?('"') && markup.end_with?('"')) ||
|
25
|
+
(markup.start_with?("'") && markup.end_with?("'"))
|
26
|
+
return markup[1..-2]
|
27
|
+
end
|
28
|
+
|
23
29
|
case markup
|
24
|
-
when nil
|
25
|
-
nil
|
26
|
-
when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING
|
27
|
-
Regexp.last_match(1)
|
28
30
|
when INTEGERS_REGEX
|
29
31
|
Regexp.last_match(1).to_i
|
30
32
|
when RANGES_REGEX
|
@@ -32,7 +34,6 @@ module Liquid
|
|
32
34
|
when FLOATS_REGEX
|
33
35
|
Regexp.last_match(1).to_f
|
34
36
|
else
|
35
|
-
markup = markup.strip
|
36
37
|
if LITERALS.key?(markup)
|
37
38
|
LITERALS[markup]
|
38
39
|
else
|
data/lib/liquid/forloop_drop.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Liquid
|
4
|
+
# @liquid_public_docs
|
5
|
+
# @liquid_type object
|
6
|
+
# @liquid_name forloop
|
7
|
+
# @liquid_summary
|
8
|
+
# Information about a parent [`for` loop](/api/liquid/tags#for).
|
4
9
|
class ForloopDrop < Drop
|
5
10
|
def initialize(name, length, parentloop)
|
6
11
|
@name = name
|
@@ -9,33 +14,71 @@ module Liquid
|
|
9
14
|
@index = 0
|
10
15
|
end
|
11
16
|
|
12
|
-
|
17
|
+
# @liquid_public_docs
|
18
|
+
# @liquid_name length
|
19
|
+
# @liquid_summary
|
20
|
+
# The total number of iterations in the loop.
|
21
|
+
# @liquid_return [number]
|
22
|
+
attr_reader :length
|
23
|
+
|
24
|
+
# @liquid_public_docs
|
25
|
+
# @liquid_name parentloop
|
26
|
+
# @liquid_summary
|
27
|
+
# The parent `forloop` object.
|
28
|
+
# @liquid_description
|
29
|
+
# If the current `for` loop isn't nested inside another `for` loop, then `nil` is returned.
|
30
|
+
# @liquid_return [forloop]
|
31
|
+
attr_reader :parentloop
|
13
32
|
|
14
33
|
def name
|
15
34
|
Usage.increment('forloop_drop_name')
|
16
35
|
@name
|
17
36
|
end
|
18
37
|
|
38
|
+
# @liquid_public_docs
|
39
|
+
# @liquid_summary
|
40
|
+
# The 1-based index of the current iteration.
|
41
|
+
# @liquid_return [number]
|
19
42
|
def index
|
20
43
|
@index + 1
|
21
44
|
end
|
22
45
|
|
46
|
+
# @liquid_public_docs
|
47
|
+
# @liquid_summary
|
48
|
+
# The 0-based index of the current iteration.
|
49
|
+
# @liquid_return [number]
|
23
50
|
def index0
|
24
51
|
@index
|
25
52
|
end
|
26
53
|
|
54
|
+
# @liquid_public_docs
|
55
|
+
# @liquid_summary
|
56
|
+
# The 1-based index of the current iteration, in reverse order.
|
57
|
+
# @liquid_return [number]
|
27
58
|
def rindex
|
28
59
|
@length - @index
|
29
60
|
end
|
30
61
|
|
62
|
+
# @liquid_public_docs
|
63
|
+
# @liquid_summary
|
64
|
+
# The 0-based index of the current iteration, in reverse order.
|
65
|
+
# @liquid_return [number]
|
31
66
|
def rindex0
|
32
67
|
@length - @index - 1
|
33
68
|
end
|
34
69
|
|
70
|
+
# @liquid_public_docs
|
71
|
+
# @liquid_summary
|
72
|
+
# Returns `true` if the current iteration is the first. Returns `false` if not.
|
73
|
+
# @liquid_return [boolean]
|
35
74
|
def first
|
36
75
|
@index == 0
|
37
76
|
end
|
38
77
|
|
78
|
+
# @liquid_public_docs
|
79
|
+
# @liquid_summary
|
80
|
+
# Returns `true` if the current iteration is the last. Returns `false` if not.
|
81
|
+
# @liquid_return [boolean]
|
39
82
|
def last
|
40
83
|
@index == @length - 1
|
41
84
|
end
|
data/lib/liquid/locales/en.yml
CHANGED
@@ -13,15 +13,16 @@
|
|
13
13
|
for_invalid_attribute: "Invalid attribute in for loop. Valid attributes are limit and offset"
|
14
14
|
if: "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
15
15
|
include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"
|
16
|
-
|
16
|
+
inline_comment_invalid: "Syntax error in tag '#' - Each line of comments must be prefixed by the '#' character"
|
17
17
|
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
|
18
|
+
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
19
|
+
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
20
|
+
tag_never_closed: "'%{block_name}' tag was never closed"
|
21
|
+
tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
|
18
22
|
unexpected_else: "%{block_name} tag does not expect 'else' tag"
|
19
23
|
unexpected_outer_tag: "Unexpected outer '%{tag}' tag"
|
20
|
-
|
24
|
+
unknown_tag: "Unknown tag '%{tag}'"
|
21
25
|
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
|
22
|
-
tag_never_closed: "'%{block_name}' tag was never closed"
|
23
|
-
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
24
|
-
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
25
26
|
argument:
|
26
27
|
include: "Argument error in tag 'include' - Illegal template name"
|
27
28
|
disabled:
|
data/lib/liquid/partial_cache.rb
CHANGED
@@ -3,16 +3,16 @@
|
|
3
3
|
module Liquid
|
4
4
|
class PartialCache
|
5
5
|
def self.load(template_name, context:, parse_context:)
|
6
|
-
cached_partials =
|
6
|
+
cached_partials = context.registers[:cached_partials]
|
7
7
|
cached = cached_partials[template_name]
|
8
8
|
return cached if cached
|
9
9
|
|
10
|
-
file_system =
|
10
|
+
file_system = context.registers[:file_system]
|
11
11
|
source = file_system.read_template_file(template_name)
|
12
12
|
|
13
13
|
parse_context.partial = true
|
14
14
|
|
15
|
-
template_factory =
|
15
|
+
template_factory = context.registers[:template_factory]
|
16
16
|
template = template_factory.for(template_name)
|
17
17
|
|
18
18
|
partial = template.parse(source, parse_context)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Liquid
|
4
|
+
class Registers
|
5
|
+
attr_reader :static
|
6
|
+
|
7
|
+
def initialize(registers = {})
|
8
|
+
@static = registers.is_a?(Registers) ? registers.static : registers
|
9
|
+
@changes = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
@changes[key] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
if @changes.key?(key)
|
18
|
+
@changes[key]
|
19
|
+
else
|
20
|
+
@static[key]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(key)
|
25
|
+
@changes.delete(key)
|
26
|
+
end
|
27
|
+
|
28
|
+
UNDEFINED = Object.new
|
29
|
+
|
30
|
+
def fetch(key, default = UNDEFINED, &block)
|
31
|
+
if @changes.key?(key)
|
32
|
+
@changes.fetch(key)
|
33
|
+
elsif default != UNDEFINED
|
34
|
+
if block_given?
|
35
|
+
@static.fetch(key, &block)
|
36
|
+
else
|
37
|
+
@static.fetch(key, default)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@static.fetch(key, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def key?(key)
|
45
|
+
@changes.key?(key) || @static.key?(key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Alias for backwards compatibility
|
50
|
+
StaticRegisters = Registers
|
51
|
+
end
|