liquid 3.0.6 → 4.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +89 -58
- data/{MIT-LICENSE → LICENSE} +0 -0
- data/lib/liquid.rb +7 -6
- data/lib/liquid/block.rb +31 -124
- data/lib/liquid/block_body.rb +54 -57
- data/lib/liquid/condition.rb +23 -22
- data/lib/liquid/context.rb +50 -42
- data/lib/liquid/document.rb +19 -9
- data/lib/liquid/drop.rb +12 -13
- data/lib/liquid/errors.rb +16 -17
- data/lib/liquid/expression.rb +15 -3
- data/lib/liquid/extensions.rb +7 -7
- data/lib/liquid/file_system.rb +3 -3
- data/lib/liquid/forloop_drop.rb +42 -0
- data/lib/liquid/i18n.rb +5 -5
- data/lib/liquid/interrupts.rb +1 -2
- data/lib/liquid/lexer.rb +6 -4
- data/lib/liquid/locales/en.yml +3 -1
- data/lib/liquid/parse_context.rb +37 -0
- data/lib/liquid/parser_switching.rb +4 -4
- data/lib/liquid/profiler.rb +18 -19
- data/lib/liquid/profiler/hooks.rb +7 -7
- data/lib/liquid/range_lookup.rb +16 -1
- data/lib/liquid/resource_limits.rb +23 -0
- data/lib/liquid/standardfilters.rb +101 -56
- data/lib/liquid/strainer.rb +4 -5
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +9 -8
- data/lib/liquid/tags/assign.rb +5 -4
- data/lib/liquid/tags/break.rb +0 -3
- data/lib/liquid/tags/capture.rb +1 -1
- data/lib/liquid/tags/case.rb +19 -12
- data/lib/liquid/tags/comment.rb +2 -2
- data/lib/liquid/tags/cycle.rb +6 -6
- data/lib/liquid/tags/decrement.rb +1 -4
- data/lib/liquid/tags/for.rb +93 -75
- data/lib/liquid/tags/if.rb +49 -44
- data/lib/liquid/tags/ifchanged.rb +0 -2
- data/lib/liquid/tags/include.rb +60 -52
- data/lib/liquid/tags/raw.rb +26 -4
- data/lib/liquid/tags/table_row.rb +12 -30
- data/lib/liquid/tags/unless.rb +3 -4
- data/lib/liquid/template.rb +23 -50
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/utils.rb +48 -8
- data/lib/liquid/variable.rb +46 -45
- data/lib/liquid/variable_lookup.rb +3 -3
- data/lib/liquid/version.rb +1 -1
- data/test/integration/assign_test.rb +8 -8
- data/test/integration/blank_test.rb +14 -14
- data/test/integration/context_test.rb +2 -2
- data/test/integration/document_test.rb +19 -0
- data/test/integration/drop_test.rb +42 -40
- data/test/integration/error_handling_test.rb +64 -45
- data/test/integration/filter_test.rb +60 -20
- data/test/integration/output_test.rb +26 -27
- data/test/integration/parsing_quirks_test.rb +15 -13
- data/test/integration/render_profiling_test.rb +20 -20
- data/test/integration/security_test.rb +5 -7
- data/test/integration/standard_filter_test.rb +119 -37
- data/test/integration/tags/break_tag_test.rb +1 -2
- data/test/integration/tags/continue_tag_test.rb +0 -1
- data/test/integration/tags/for_tag_test.rb +133 -98
- data/test/integration/tags/if_else_tag_test.rb +75 -77
- data/test/integration/tags/include_tag_test.rb +23 -30
- data/test/integration/tags/increment_tag_test.rb +10 -11
- data/test/integration/tags/raw_tag_test.rb +7 -1
- data/test/integration/tags/standard_tag_test.rb +121 -122
- data/test/integration/tags/statements_test.rb +3 -5
- data/test/integration/tags/table_row_test.rb +20 -19
- data/test/integration/tags/unless_else_tag_test.rb +6 -6
- data/test/integration/template_test.rb +91 -45
- data/test/integration/variable_test.rb +23 -13
- data/test/test_helper.rb +33 -5
- data/test/unit/block_unit_test.rb +6 -5
- data/test/unit/condition_unit_test.rb +82 -77
- data/test/unit/context_unit_test.rb +48 -57
- data/test/unit/file_system_unit_test.rb +3 -3
- data/test/unit/i18n_unit_test.rb +2 -2
- data/test/unit/lexer_unit_test.rb +11 -8
- data/test/unit/parser_unit_test.rb +2 -2
- data/test/unit/regexp_unit_test.rb +1 -1
- data/test/unit/strainer_unit_test.rb +13 -2
- data/test/unit/tag_unit_test.rb +7 -2
- data/test/unit/tags/case_tag_unit_test.rb +1 -1
- data/test/unit/tags/for_tag_unit_test.rb +2 -2
- data/test/unit/tags/if_tag_unit_test.rb +1 -1
- data/test/unit/template_unit_test.rb +6 -5
- data/test/unit/tokenizer_unit_test.rb +24 -7
- data/test/unit/variable_unit_test.rb +60 -43
- metadata +44 -41
- data/lib/liquid/module_ex.rb +0 -62
- data/lib/liquid/token.rb +0 -18
- data/test/unit/module_ex_unit_test.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cb85d26c5a294b870e0624188f36b3a7e8c8ba7
|
4
|
+
data.tar.gz: 1eea59fdf71a08c68a61dc240bf6655e244c7777
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce2003217fb7c25700c641d5af17b6b41e5247f062dba6ae34869abde88d169fd1407b210ce00f03465742a105294e202b97b98698a95a2992cdeaad66cd8429
|
7
|
+
data.tar.gz: 9ff0d24f24b9c9411ddfa3b74577e6945dfc2b69f01508c9da6d409e82bc20629f0448110b3ee4e2f35c3e4c307c0c1e75e656659f3c78bb8fdbfd2b168a9831
|
data/History.md
CHANGED
@@ -1,4 +1,35 @@
|
|
1
|
-
# Liquid
|
1
|
+
# Liquid Change Log
|
2
|
+
|
3
|
+
## 4.0.0 / not yet released / branch "master"
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
* Add url_decode filter to invert url_encode (#645) [Larry Archer]
|
7
|
+
* Add global_filter to apply a filter to all output (#610) [Loren Hale]
|
8
|
+
* Add compact filter (#600) [Carson Reinke]
|
9
|
+
* Rename deprecated "has_key?" and "has_interrupt?" methods (#593) [Florian Weingarten]
|
10
|
+
* Include template name with line numbers in render errors (574) [Dylan Thacker-Smith]
|
11
|
+
* Add sort_natural filter (#554) [Martin Hanzel]
|
12
|
+
* Add forloop.parentloop as a reference to the parent loop (#520) [Justin Li]
|
13
|
+
* Block parsing moved to BlockBody class (#458) [Dylan Thacker-Smith]
|
14
|
+
* Add concat filter to concatenate arrays (#429) [Diogo Beato]
|
15
|
+
* Ruby 1.9 support dropped (#491) [Justin Li]
|
16
|
+
* Liquid::Template.file_system's read_template_file method is no longer passed the context. (#441) [James Reid-Smith]
|
17
|
+
* Remove support for `liquid_methods`
|
18
|
+
* Rename Drop method `before_method` as `liquid_method_missing` (#661) [Thierry Joyal]
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
* Fix sort filter behaviour with empty array input (#652) [Marcel Cary]
|
22
|
+
* Fix test failure under certain timezones (#631) [Dylan Thacker-Smith]
|
23
|
+
* Fix bug in uniq filter (#595) [Florian Weingarten]
|
24
|
+
* Fix bug when "blank" and "empty" are used as variable names (#592) [Florian Weingarten]
|
25
|
+
* Fix condition parse order in strict mode (#569) [Justin Li]
|
26
|
+
* Fix naming of the "context variable" when dynamically including a template (#559) [Justin Li]
|
27
|
+
* Gracefully accept empty strings in the date filter (#555) [Loren Hale]
|
28
|
+
* Fix capturing into variables with a hyphen in the name (#505) [Florian Weingarten]
|
29
|
+
* Fix case sensitivity regression in date standard filter (#499) [Kelley Reynolds]
|
30
|
+
* Disallow filters with no variable in strict mode (#475) [Justin Li]
|
31
|
+
* Disallow variable names in the strict parser that are not valid in the lax parser (#463) [Justin Li]
|
32
|
+
* Fix BlockBody#warnings taking exponential time to compute (#486) [Justin Li]
|
2
33
|
|
3
34
|
## 3.0.5 / 2015-07-23 / branch "3-0-stable"
|
4
35
|
|
@@ -10,11 +41,11 @@
|
|
10
41
|
|
11
42
|
## 3.0.3 / 2015-05-28
|
12
43
|
|
13
|
-
* Fix condition parse order in strict mode (#569) [Justin Li
|
44
|
+
* Fix condition parse order in strict mode (#569) [Justin Li]
|
14
45
|
|
15
46
|
## 3.0.2 / 2015-04-24
|
16
47
|
|
17
|
-
* Expose VariableLookup private members (#551) [Justin Li
|
48
|
+
* Expose VariableLookup private members (#551) [Justin Li]
|
18
49
|
* Documentation fixes
|
19
50
|
|
20
51
|
## 3.0.1 / 2015-01-23
|
@@ -23,38 +54,38 @@
|
|
23
54
|
|
24
55
|
## 3.0.0 / 2014-11-12
|
25
56
|
|
26
|
-
* Removed Block#end_tag. Instead, override parse with `super` followed by your code. See #446 [Dylan Thacker-Smith
|
27
|
-
* Fixed condition with wrong data types
|
28
|
-
* Add url_encode to standard filters
|
29
|
-
* Add uniq to standard filters [Florian Weingarten
|
30
|
-
* Add exception_handler feature
|
31
|
-
* Optimize variable parsing to avoid repeated regex evaluation during template rendering #383 [Jason Hiltz-Laforge
|
32
|
-
* Optimize checking for block interrupts to reduce object allocation #380 [Jason Hiltz-Laforge
|
33
|
-
* Properly set context rethrow_errors on render! #349 [Thierry Joyal
|
34
|
-
* Fix broken rendering of variables which are equal to false
|
35
|
-
* Remove ActionView template handler [Dylan Thacker-Smith
|
36
|
-
* Freeze lots of string literals for new Ruby 2.1 optimization
|
37
|
-
* Allow newlines in tags and variables
|
38
|
-
* Tag#parse is called after initialize, which now takes options instead of tokens as the 3rd argument. See #321 [Dylan Thacker-Smith
|
39
|
-
* Raise `Liquid::ArgumentError` instead of `::ArgumentError` when filter has wrong number of arguments #309 [Bogdan Gusiev
|
40
|
-
* Add a to_s default for liquid drops
|
41
|
-
* Add strip, lstrip, and rstrip to standard filters [Florian Weingarten
|
42
|
-
* Make if, for & case tags return complete and consistent nodelists
|
43
|
-
* Prevent arbitrary method invocation on condition objects
|
44
|
-
* Don't call to_sym when creating conditions for security reasons
|
45
|
-
* Fix resource counting bug with respond_to?(:length)
|
46
|
-
* Allow specifying custom patterns for template filenames
|
47
|
-
* Allow drops to optimize loading a slice of elements
|
48
|
-
* Support for passing variables to snippets in subdirs
|
49
|
-
* Add a class cache to avoid runtime extend calls
|
50
|
-
* Remove some legacy Ruby 1.8 compatibility code
|
51
|
-
* Add default filter to standard filters
|
52
|
-
* Add optional strict parsing and warn parsing
|
53
|
-
* Add I18n syntax error translation
|
54
|
-
* Make sort filter work on enumerable drops
|
55
|
-
* Fix clashing method names in enumerable drops
|
56
|
-
* Make map filter work on enumerable drops
|
57
|
-
* Improved whitespace stripping for blank blocks, related to #216 [Florian Weingarten
|
57
|
+
* Removed Block#end_tag. Instead, override parse with `super` followed by your code. See #446 [Dylan Thacker-Smith]
|
58
|
+
* Fixed condition with wrong data types (#423) [Bogdan Gusiev]
|
59
|
+
* Add url_encode to standard filters (#421) [Derrick Reimer]
|
60
|
+
* Add uniq to standard filters [Florian Weingarten]
|
61
|
+
* Add exception_handler feature (#397) and #254 [Bogdan Gusiev, Florian Weingarten]
|
62
|
+
* Optimize variable parsing to avoid repeated regex evaluation during template rendering #383 [Jason Hiltz-Laforge]
|
63
|
+
* Optimize checking for block interrupts to reduce object allocation #380 [Jason Hiltz-Laforge]
|
64
|
+
* Properly set context rethrow_errors on render! #349 [Thierry Joyal]
|
65
|
+
* Fix broken rendering of variables which are equal to false (#345) [Florian Weingarten]
|
66
|
+
* Remove ActionView template handler [Dylan Thacker-Smith]
|
67
|
+
* Freeze lots of string literals for new Ruby 2.1 optimization (#297) [Florian Weingarten]
|
68
|
+
* Allow newlines in tags and variables (#324) [Dylan Thacker-Smith]
|
69
|
+
* Tag#parse is called after initialize, which now takes options instead of tokens as the 3rd argument. See #321 [Dylan Thacker-Smith]
|
70
|
+
* Raise `Liquid::ArgumentError` instead of `::ArgumentError` when filter has wrong number of arguments #309 [Bogdan Gusiev]
|
71
|
+
* Add a to_s default for liquid drops (#306) [Adam Doeler]
|
72
|
+
* Add strip, lstrip, and rstrip to standard filters [Florian Weingarten]
|
73
|
+
* Make if, for & case tags return complete and consistent nodelists (#250) [Nick Jones]
|
74
|
+
* Prevent arbitrary method invocation on condition objects (#274) [Dylan Thacker-Smith]
|
75
|
+
* Don't call to_sym when creating conditions for security reasons (#273) [Bouke van der Bijl]
|
76
|
+
* Fix resource counting bug with respond_to?(:length) (#263) [Florian Weingarten]
|
77
|
+
* Allow specifying custom patterns for template filenames (#284) [Andrei Gladkyi]
|
78
|
+
* Allow drops to optimize loading a slice of elements (#282) [Tom Burns]
|
79
|
+
* Support for passing variables to snippets in subdirs (#271) [Joost Hietbrink]
|
80
|
+
* Add a class cache to avoid runtime extend calls (#249) [James Tucker]
|
81
|
+
* Remove some legacy Ruby 1.8 compatibility code (#276) [Florian Weingarten]
|
82
|
+
* Add default filter to standard filters (#267) [Derrick Reimer]
|
83
|
+
* Add optional strict parsing and warn parsing (#235) [Tristan Hume]
|
84
|
+
* Add I18n syntax error translation (#241) [Simon Hørup Eskildsen, Sirupsen]
|
85
|
+
* Make sort filter work on enumerable drops (#239) [Florian Weingarten]
|
86
|
+
* Fix clashing method names in enumerable drops (#238) [Florian Weingarten]
|
87
|
+
* Make map filter work on enumerable drops (#233) [Florian Weingarten]
|
88
|
+
* Improved whitespace stripping for blank blocks, related to #216 [Florian Weingarten]
|
58
89
|
|
59
90
|
## 2.6.3 / 2015-07-23 / branch "2-6-stable"
|
60
91
|
|
@@ -67,8 +98,8 @@
|
|
67
98
|
## 2.6.1 / 2014-01-10
|
68
99
|
|
69
100
|
Security fix, cherry-picked from master (4e14a65):
|
70
|
-
* Don't call to_sym when creating conditions for security reasons
|
71
|
-
* Prevent arbitrary method invocation on condition objects
|
101
|
+
* Don't call to_sym when creating conditions for security reasons (#273) [Bouke van der Bijl]
|
102
|
+
* Prevent arbitrary method invocation on condition objects (#274) [Dylan Thacker-Smith]
|
72
103
|
|
73
104
|
## 2.6.0 / 2013-11-25
|
74
105
|
|
@@ -76,37 +107,37 @@ IMPORTANT: Liquid 2.6 is going to be the last version of Liquid which maintains
|
|
76
107
|
The following releases will only be tested against Ruby 1.9 and Ruby 2.0 and are likely to break on Ruby 1.8.
|
77
108
|
|
78
109
|
* Bugfix for #106: fix example servlet [gnowoel]
|
79
|
-
* Bugfix for #97: strip_html filter supports multi-line tags [Jo Liss
|
80
|
-
* Bugfix for #114: strip_html filter supports style tags [James Allardice
|
81
|
-
* Bugfix for #117: 'now' support for date filter in Ruby 1.9 [Notre Dame Webgroup
|
82
|
-
* Bugfix for #166: truncate filter on UTF-8 strings with Ruby 1.8 [Florian Weingarten
|
83
|
-
* Bugfix for #204: 'raw' parsing bug [Florian Weingarten
|
84
|
-
* Bugfix for #150: 'for' parsing bug [Peter Schröder
|
85
|
-
* Bugfix for #126: Strip CRLF in strip_newline [Peter Schröder
|
86
|
-
* Bugfix for #174, "can't convert Fixnum into String" for "replace" [
|
87
|
-
* Allow a Liquid::Drop to be passed into Template#render [Daniel Huckstep
|
88
|
-
* Resource limits [Florian Weingarten
|
89
|
-
* Add reverse filter [Jay Strybis
|
110
|
+
* Bugfix for #97: strip_html filter supports multi-line tags [Jo Liss]
|
111
|
+
* Bugfix for #114: strip_html filter supports style tags [James Allardice]
|
112
|
+
* Bugfix for #117: 'now' support for date filter in Ruby 1.9 [Notre Dame Webgroup]
|
113
|
+
* Bugfix for #166: truncate filter on UTF-8 strings with Ruby 1.8 [Florian Weingarten]
|
114
|
+
* Bugfix for #204: 'raw' parsing bug [Florian Weingarten]
|
115
|
+
* Bugfix for #150: 'for' parsing bug [Peter Schröder]
|
116
|
+
* Bugfix for #126: Strip CRLF in strip_newline [Peter Schröder]
|
117
|
+
* Bugfix for #174, "can't convert Fixnum into String" for "replace" [jsw0528]
|
118
|
+
* Allow a Liquid::Drop to be passed into Template#render [Daniel Huckstep]
|
119
|
+
* Resource limits [Florian Weingarten]
|
120
|
+
* Add reverse filter [Jay Strybis]
|
90
121
|
* Add utf-8 support
|
91
|
-
* Use array instead of Hash to keep the registered filters [Tasos Stathopoulos
|
92
|
-
* Cache tokenized partial templates [Tom Burns
|
93
|
-
* Avoid warnings in Ruby 1.9.3 [Marcus Stollsteimer
|
94
|
-
* Better documentation for 'include' tag (closes #163) [Peter Schröder
|
95
|
-
* Use of BigDecimal on filters to have better precision (closes #155) [Arthur Nogueira Neves
|
122
|
+
* Use array instead of Hash to keep the registered filters [Tasos Stathopoulos]
|
123
|
+
* Cache tokenized partial templates [Tom Burns]
|
124
|
+
* Avoid warnings in Ruby 1.9.3 [Marcus Stollsteimer]
|
125
|
+
* Better documentation for 'include' tag (closes #163) [Peter Schröder]
|
126
|
+
* Use of BigDecimal on filters to have better precision (closes #155) [Arthur Nogueira Neves]
|
96
127
|
|
97
128
|
## 2.5.5 / 2014-01-10 / branch "2-5-stable"
|
98
129
|
|
99
130
|
Security fix, cherry-picked from master (4e14a65):
|
100
|
-
* Don't call to_sym when creating conditions for security reasons
|
101
|
-
* Prevent arbitrary method invocation on condition objects
|
131
|
+
* Don't call to_sym when creating conditions for security reasons (#273) [Bouke van der Bijl]
|
132
|
+
* Prevent arbitrary method invocation on condition objects (#274) [Dylan Thacker-Smith]
|
102
133
|
|
103
134
|
## 2.5.4 / 2013-11-11
|
104
135
|
|
105
|
-
* Fix "can't convert Fixnum into String" for "replace"
|
136
|
+
* Fix "can't convert Fixnum into String" for "replace" (#173), [jsw0528]
|
106
137
|
|
107
138
|
## 2.5.3 / 2013-10-09
|
108
139
|
|
109
|
-
* #232, #234, #237: Fix map filter bugs [Florian Weingarten
|
140
|
+
* #232, #234, #237: Fix map filter bugs [Florian Weingarten]
|
110
141
|
|
111
142
|
## 2.5.2 / 2013-09-03 / deleted
|
112
143
|
|
@@ -114,7 +145,7 @@ Yanked from rubygems, as it contained too many changes that broke compatibility.
|
|
114
145
|
|
115
146
|
## 2.5.1 / 2013-07-24
|
116
147
|
|
117
|
-
* #230: Fix security issue with map filter, Use invoke_drop in map filter [Florian Weingarten
|
148
|
+
* #230: Fix security issue with map filter, Use invoke_drop in map filter [Florian Weingarten]
|
118
149
|
|
119
150
|
## 2.5.0 / 2013-03-06
|
120
151
|
|
data/{MIT-LICENSE → LICENSE}
RENAMED
File without changes
|
data/lib/liquid.rb
CHANGED
@@ -48,6 +48,8 @@ require 'liquid/lexer'
|
|
48
48
|
require 'liquid/parser'
|
49
49
|
require 'liquid/i18n'
|
50
50
|
require 'liquid/drop'
|
51
|
+
require 'liquid/tablerowloop_drop'
|
52
|
+
require 'liquid/forloop_drop'
|
51
53
|
require 'liquid/extensions'
|
52
54
|
require 'liquid/errors'
|
53
55
|
require 'liquid/interrupts'
|
@@ -57,21 +59,20 @@ require 'liquid/context'
|
|
57
59
|
require 'liquid/parser_switching'
|
58
60
|
require 'liquid/tag'
|
59
61
|
require 'liquid/block'
|
62
|
+
require 'liquid/block_body'
|
60
63
|
require 'liquid/document'
|
61
64
|
require 'liquid/variable'
|
62
65
|
require 'liquid/variable_lookup'
|
63
66
|
require 'liquid/range_lookup'
|
64
67
|
require 'liquid/file_system'
|
68
|
+
require 'liquid/resource_limits'
|
65
69
|
require 'liquid/template'
|
66
70
|
require 'liquid/standardfilters'
|
67
71
|
require 'liquid/condition'
|
68
|
-
require 'liquid/module_ex'
|
69
72
|
require 'liquid/utils'
|
70
|
-
require 'liquid/
|
73
|
+
require 'liquid/tokenizer'
|
74
|
+
require 'liquid/parse_context'
|
71
75
|
|
72
76
|
# Load all the tags of the standard library
|
73
77
|
#
|
74
|
-
Dir[
|
75
|
-
|
76
|
-
require 'liquid/profiler'
|
77
|
-
require 'liquid/profiler/hooks'
|
78
|
+
Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f }
|
data/lib/liquid/block.rb
CHANGED
@@ -1,90 +1,39 @@
|
|
1
1
|
module Liquid
|
2
2
|
class Block < Tag
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
VARSTART = "{{".freeze
|
7
|
-
|
8
|
-
def blank?
|
9
|
-
@blank
|
3
|
+
def initialize(tag_name, markup, options)
|
4
|
+
super
|
5
|
+
@blank = true
|
10
6
|
end
|
11
7
|
|
12
8
|
def parse(tokens)
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@nodelist.clear
|
16
|
-
|
17
|
-
while token = tokens.shift
|
18
|
-
begin
|
19
|
-
unless token.empty?
|
20
|
-
case
|
21
|
-
when token.start_with?(TAGSTART)
|
22
|
-
if token =~ FullToken
|
23
|
-
|
24
|
-
# if we found the proper block delimiter just end parsing here and let the outer block
|
25
|
-
# proceed
|
26
|
-
return if block_delimiter == $1
|
27
|
-
|
28
|
-
# fetch the tag from registered blocks
|
29
|
-
if tag = Template.tags[$1]
|
30
|
-
markup = token.is_a?(Token) ? token.child($2) : $2
|
31
|
-
new_tag = tag.parse($1, markup, tokens, @options)
|
32
|
-
new_tag.line_number = token.line_number if token.is_a?(Token)
|
33
|
-
@blank &&= new_tag.blank?
|
34
|
-
@nodelist << new_tag
|
35
|
-
else
|
36
|
-
# this tag is not registered with the system
|
37
|
-
# pass it to the current block for special handling or error reporting
|
38
|
-
unknown_tag($1, $2, tokens)
|
39
|
-
end
|
40
|
-
else
|
41
|
-
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
|
42
|
-
end
|
43
|
-
when token.start_with?(VARSTART)
|
44
|
-
new_var = create_variable(token)
|
45
|
-
new_var.line_number = token.line_number if token.is_a?(Token)
|
46
|
-
@nodelist << new_var
|
47
|
-
@blank = false
|
48
|
-
else
|
49
|
-
@nodelist << token
|
50
|
-
@blank &&= (token =~ /\A\s*\z/)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
rescue SyntaxError => e
|
54
|
-
e.set_line_number_from_token(token)
|
55
|
-
raise
|
56
|
-
end
|
9
|
+
@body = BlockBody.new
|
10
|
+
while parse_body(@body, tokens)
|
57
11
|
end
|
58
|
-
|
59
|
-
# Make sure that it's ok to end parsing in the current block.
|
60
|
-
# Effectively this method will throw an exception unless the current block is
|
61
|
-
# of type Document
|
62
|
-
assert_missing_delimitation!
|
63
12
|
end
|
64
13
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
all_warnings.concat(@warnings) if @warnings
|
14
|
+
def render(context)
|
15
|
+
@body.render(context)
|
16
|
+
end
|
69
17
|
|
70
|
-
|
71
|
-
|
72
|
-
|
18
|
+
def blank?
|
19
|
+
@blank
|
20
|
+
end
|
73
21
|
|
74
|
-
|
22
|
+
def nodelist
|
23
|
+
@body.nodelist
|
75
24
|
end
|
76
25
|
|
77
|
-
def unknown_tag(tag,
|
26
|
+
def unknown_tag(tag, _params, _tokens)
|
78
27
|
case tag
|
79
28
|
when 'else'.freeze
|
80
|
-
raise SyntaxError.new(
|
81
|
-
|
29
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.unexpected_else".freeze,
|
30
|
+
block_name: block_name))
|
82
31
|
when 'end'.freeze
|
83
|
-
raise SyntaxError.new(
|
84
|
-
|
85
|
-
|
32
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.invalid_delimiter".freeze,
|
33
|
+
block_name: block_name,
|
34
|
+
block_delimiter: block_delimiter))
|
86
35
|
else
|
87
|
-
raise SyntaxError.new(
|
36
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.unknown_tag".freeze, tag: tag))
|
88
37
|
end
|
89
38
|
end
|
90
39
|
|
@@ -96,65 +45,23 @@ module Liquid
|
|
96
45
|
@block_delimiter ||= "end#{block_name}"
|
97
46
|
end
|
98
47
|
|
99
|
-
def create_variable(token)
|
100
|
-
token.scan(ContentOfVariable) do |content|
|
101
|
-
markup = token.is_a?(Token) ? token.child(content.first) : content.first
|
102
|
-
return Variable.new(markup, @options)
|
103
|
-
end
|
104
|
-
raise SyntaxError.new(options[:locale].t("errors.syntax.variable_termination".freeze, :token => token, :tag_end => VariableEnd.inspect))
|
105
|
-
end
|
106
|
-
|
107
|
-
def render(context)
|
108
|
-
render_all(@nodelist, context)
|
109
|
-
end
|
110
|
-
|
111
48
|
protected
|
112
49
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
def render_all(list, context)
|
118
|
-
output = []
|
119
|
-
context.resource_limits[:render_length_current] = 0
|
120
|
-
context.resource_limits[:render_score_current] += list.length
|
50
|
+
def parse_body(body, tokens)
|
51
|
+
body.parse(tokens, parse_context) do |end_tag_name, end_tag_params|
|
52
|
+
@blank &&= body.blank?
|
121
53
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
begin
|
127
|
-
# If we get an Interrupt that means the block must stop processing. An
|
128
|
-
# Interrupt is any command that stops block execution such as {% break %}
|
129
|
-
# or {% continue %}
|
130
|
-
if token.is_a? Continue or token.is_a? Break
|
131
|
-
context.push_interrupt(token.interrupt)
|
132
|
-
break
|
133
|
-
end
|
134
|
-
|
135
|
-
token_output = render_token(token, context)
|
136
|
-
|
137
|
-
unless token.is_a?(Block) && token.blank?
|
138
|
-
output << token_output
|
139
|
-
end
|
140
|
-
rescue MemoryError => e
|
141
|
-
raise e
|
142
|
-
rescue ::StandardError => e
|
143
|
-
output << (context.handle_error(e, token))
|
54
|
+
return false if end_tag_name == block_delimiter
|
55
|
+
unless end_tag_name
|
56
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name))
|
144
57
|
end
|
145
|
-
end
|
146
58
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
def render_token(token, context)
|
151
|
-
token_output = (token.respond_to?(:render) ? token.render(context) : token)
|
152
|
-
context.increment_used_resources(:render_length_current, token_output)
|
153
|
-
if context.resource_limits_reached?
|
154
|
-
context.resource_limits[:reached] = true
|
155
|
-
raise MemoryError.new("Memory limits exceeded".freeze)
|
59
|
+
# this tag is not registered with the system
|
60
|
+
# pass it to the current block for special handling or error reporting
|
61
|
+
unknown_tag(end_tag_name, end_tag_params, tokens)
|
156
62
|
end
|
157
|
-
|
63
|
+
|
64
|
+
true
|
158
65
|
end
|
159
66
|
end
|
160
67
|
end
|
data/lib/liquid/block_body.rb
CHANGED
@@ -12,44 +12,37 @@ module Liquid
|
|
12
12
|
@blank = true
|
13
13
|
end
|
14
14
|
|
15
|
-
def parse(
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@blank &&= new_tag.blank?
|
30
|
-
@nodelist << new_tag
|
31
|
-
else
|
32
|
-
# end parsing if we reach an unknown tag and let the caller decide
|
33
|
-
# determine how to proceed
|
34
|
-
return yield tag_name, markup
|
35
|
-
end
|
15
|
+
def parse(tokenizer, parse_context)
|
16
|
+
parse_context.line_number = tokenizer.line_number
|
17
|
+
while token = tokenizer.shift
|
18
|
+
unless token.empty?
|
19
|
+
case
|
20
|
+
when token.start_with?(TAGSTART)
|
21
|
+
if token =~ FullToken
|
22
|
+
tag_name = $1
|
23
|
+
markup = $2
|
24
|
+
# fetch the tag from registered blocks
|
25
|
+
if tag = registered_tags[tag_name]
|
26
|
+
new_tag = tag.parse(tag_name, markup, tokenizer, parse_context)
|
27
|
+
@blank &&= new_tag.blank?
|
28
|
+
@nodelist << new_tag
|
36
29
|
else
|
37
|
-
|
30
|
+
# end parsing if we reach an unknown tag and let the caller decide
|
31
|
+
# determine how to proceed
|
32
|
+
return yield tag_name, markup
|
38
33
|
end
|
39
|
-
when token.start_with?(VARSTART)
|
40
|
-
new_var = create_variable(token, options)
|
41
|
-
new_var.line_number = token.line_number if token.is_a?(Token)
|
42
|
-
@nodelist << new_var
|
43
|
-
@blank = false
|
44
34
|
else
|
45
|
-
|
46
|
-
@blank &&= !!(token =~ /\A\s*\z/)
|
35
|
+
raise_missing_tag_terminator(token, parse_context)
|
47
36
|
end
|
37
|
+
when token.start_with?(VARSTART)
|
38
|
+
@nodelist << create_variable(token, parse_context)
|
39
|
+
@blank = false
|
40
|
+
else
|
41
|
+
@nodelist << token
|
42
|
+
@blank &&= !!(token =~ /\A\s*\z/)
|
48
43
|
end
|
49
|
-
rescue SyntaxError => e
|
50
|
-
e.set_line_number_from_token(token)
|
51
|
-
raise
|
52
44
|
end
|
45
|
+
parse_context.line_number = tokenizer.line_number
|
53
46
|
end
|
54
47
|
|
55
48
|
yield nil, nil
|
@@ -59,41 +52,32 @@ module Liquid
|
|
59
52
|
@blank
|
60
53
|
end
|
61
54
|
|
62
|
-
def warnings
|
63
|
-
all_warnings = []
|
64
|
-
nodelist.each do |node|
|
65
|
-
all_warnings.concat(node.warnings) if node.respond_to?(:warnings) && node.warnings
|
66
|
-
end
|
67
|
-
all_warnings
|
68
|
-
end
|
69
|
-
|
70
55
|
def render(context)
|
71
56
|
output = []
|
72
|
-
context.resource_limits
|
73
|
-
context.resource_limits[:render_score_current] += @nodelist.length
|
57
|
+
context.resource_limits.render_score += @nodelist.length
|
74
58
|
|
75
59
|
@nodelist.each do |token|
|
76
60
|
# Break out if we have any unhanded interrupts.
|
77
|
-
break if context.
|
61
|
+
break if context.interrupt?
|
78
62
|
|
79
63
|
begin
|
80
64
|
# If we get an Interrupt that means the block must stop processing. An
|
81
65
|
# Interrupt is any command that stops block execution such as {% break %}
|
82
66
|
# or {% continue %}
|
83
|
-
if token.is_a?(Continue)
|
67
|
+
if token.is_a?(Continue) || token.is_a?(Break)
|
84
68
|
context.push_interrupt(token.interrupt)
|
85
69
|
break
|
86
70
|
end
|
87
71
|
|
88
|
-
|
72
|
+
node_output = render_node(token, context)
|
89
73
|
|
90
74
|
unless token.is_a?(Block) && token.blank?
|
91
|
-
output <<
|
75
|
+
output << node_output
|
92
76
|
end
|
93
77
|
rescue MemoryError => e
|
94
78
|
raise e
|
95
79
|
rescue ::StandardError => e
|
96
|
-
output << context.handle_error(e, token)
|
80
|
+
output << context.handle_error(e, token.line_number)
|
97
81
|
end
|
98
82
|
end
|
99
83
|
|
@@ -102,22 +86,35 @@ module Liquid
|
|
102
86
|
|
103
87
|
private
|
104
88
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
89
|
+
def render_node(node, context)
|
90
|
+
node_output = (node.respond_to?(:render) ? node.render(context) : node)
|
91
|
+
node_output = node_output.is_a?(Array) ? node_output.join : node_output.to_s
|
92
|
+
|
93
|
+
context.resource_limits.render_length += node_output.length
|
94
|
+
if context.resource_limits.reached?
|
110
95
|
raise MemoryError.new("Memory limits exceeded".freeze)
|
111
96
|
end
|
112
|
-
|
97
|
+
node_output
|
113
98
|
end
|
114
99
|
|
115
|
-
def create_variable(token,
|
100
|
+
def create_variable(token, parse_context)
|
116
101
|
token.scan(ContentOfVariable) do |content|
|
117
|
-
markup =
|
118
|
-
return Variable.new(markup,
|
102
|
+
markup = content.first
|
103
|
+
return Variable.new(markup, parse_context)
|
119
104
|
end
|
120
|
-
|
105
|
+
raise_missing_variable_terminator(token, parse_context)
|
106
|
+
end
|
107
|
+
|
108
|
+
def raise_missing_tag_terminator(token, parse_context)
|
109
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_termination".freeze, token: token, tag_end: TagEnd.inspect))
|
110
|
+
end
|
111
|
+
|
112
|
+
def raise_missing_variable_terminator(token, parse_context)
|
113
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.variable_termination".freeze, token: token, tag_end: VariableEnd.inspect))
|
114
|
+
end
|
115
|
+
|
116
|
+
def registered_tags
|
117
|
+
Template.tags
|
121
118
|
end
|
122
119
|
end
|
123
120
|
end
|