liquid 2.6.3 → 3.0.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 +46 -13
- data/README.md +27 -2
- data/lib/liquid/block.rb +85 -51
- data/lib/liquid/block_body.rb +123 -0
- data/lib/liquid/condition.rb +26 -15
- data/lib/liquid/context.rb +106 -140
- data/lib/liquid/document.rb +3 -3
- data/lib/liquid/drop.rb +17 -1
- data/lib/liquid/errors.rb +50 -2
- data/lib/liquid/expression.rb +33 -0
- data/lib/liquid/file_system.rb +17 -6
- data/lib/liquid/i18n.rb +39 -0
- data/lib/liquid/interrupts.rb +1 -1
- data/lib/liquid/lexer.rb +51 -0
- data/lib/liquid/locales/en.yml +22 -0
- data/lib/liquid/parser.rb +90 -0
- data/lib/liquid/parser_switching.rb +31 -0
- data/lib/liquid/profiler/hooks.rb +23 -0
- data/lib/liquid/profiler.rb +159 -0
- data/lib/liquid/range_lookup.rb +22 -0
- data/lib/liquid/standardfilters.rb +143 -55
- data/lib/liquid/strainer.rb +14 -4
- data/lib/liquid/tag.rb +25 -9
- data/lib/liquid/tags/assign.rb +12 -9
- data/lib/liquid/tags/break.rb +1 -1
- data/lib/liquid/tags/capture.rb +10 -8
- data/lib/liquid/tags/case.rb +13 -13
- data/lib/liquid/tags/comment.rb +9 -2
- data/lib/liquid/tags/continue.rb +1 -4
- data/lib/liquid/tags/cycle.rb +5 -7
- data/lib/liquid/tags/decrement.rb +3 -4
- data/lib/liquid/tags/for.rb +69 -36
- data/lib/liquid/tags/if.rb +52 -25
- data/lib/liquid/tags/ifchanged.rb +3 -3
- data/lib/liquid/tags/include.rb +19 -8
- data/lib/liquid/tags/increment.rb +4 -8
- data/lib/liquid/tags/raw.rb +4 -7
- data/lib/liquid/tags/table_row.rb +73 -0
- data/lib/liquid/tags/unless.rb +2 -4
- data/lib/liquid/template.rb +124 -14
- data/lib/liquid/token.rb +18 -0
- data/lib/liquid/utils.rb +13 -4
- data/lib/liquid/variable.rb +103 -25
- data/lib/liquid/variable_lookup.rb +78 -0
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +19 -11
- data/test/fixtures/en_locale.yml +9 -0
- data/test/{liquid → integration}/assign_test.rb +18 -1
- data/test/integration/blank_test.rb +106 -0
- data/test/{liquid → integration}/capture_test.rb +3 -3
- data/test/integration/context_test.rb +32 -0
- data/test/integration/drop_test.rb +271 -0
- data/test/integration/error_handling_test.rb +207 -0
- data/test/{liquid → integration}/filter_test.rb +11 -11
- data/test/integration/hash_ordering_test.rb +23 -0
- data/test/{liquid → integration}/output_test.rb +13 -13
- data/test/integration/parsing_quirks_test.rb +116 -0
- data/test/integration/render_profiling_test.rb +154 -0
- data/test/{liquid → integration}/security_test.rb +10 -10
- data/test/{liquid → integration}/standard_filter_test.rb +148 -32
- data/test/{liquid → integration}/tags/break_tag_test.rb +1 -1
- data/test/{liquid → integration}/tags/continue_tag_test.rb +1 -1
- data/test/{liquid → integration}/tags/for_tag_test.rb +80 -2
- data/test/{liquid → integration}/tags/if_else_tag_test.rb +24 -21
- data/test/integration/tags/include_tag_test.rb +234 -0
- data/test/{liquid → integration}/tags/increment_tag_test.rb +1 -1
- data/test/{liquid → integration}/tags/raw_tag_test.rb +2 -1
- data/test/{liquid → integration}/tags/standard_tag_test.rb +28 -26
- data/test/integration/tags/statements_test.rb +113 -0
- data/test/{liquid/tags/html_tag_test.rb → integration/tags/table_row_test.rb} +5 -5
- data/test/{liquid → integration}/tags/unless_else_tag_test.rb +1 -1
- data/test/{liquid → integration}/template_test.rb +81 -45
- data/test/integration/variable_test.rb +82 -0
- data/test/test_helper.rb +73 -20
- data/test/{liquid/block_test.rb → unit/block_unit_test.rb} +2 -5
- data/test/{liquid/condition_test.rb → unit/condition_unit_test.rb} +23 -1
- data/test/{liquid/context_test.rb → unit/context_unit_test.rb} +39 -25
- data/test/{liquid/file_system_test.rb → unit/file_system_unit_test.rb} +11 -5
- data/test/unit/i18n_unit_test.rb +37 -0
- data/test/unit/lexer_unit_test.rb +48 -0
- data/test/{liquid/module_ex_test.rb → unit/module_ex_unit_test.rb} +7 -7
- data/test/unit/parser_unit_test.rb +82 -0
- data/test/{liquid/regexp_test.rb → unit/regexp_unit_test.rb} +3 -3
- data/test/{liquid/strainer_test.rb → unit/strainer_unit_test.rb} +20 -1
- data/test/unit/tag_unit_test.rb +16 -0
- data/test/unit/tags/case_tag_unit_test.rb +10 -0
- data/test/unit/tags/for_tag_unit_test.rb +13 -0
- data/test/unit/tags/if_tag_unit_test.rb +8 -0
- data/test/unit/template_unit_test.rb +69 -0
- data/test/unit/tokenizer_unit_test.rb +38 -0
- data/test/unit/variable_unit_test.rb +139 -0
- metadata +135 -67
- data/lib/extras/liquid_view.rb +0 -51
- data/lib/liquid/htmltags.rb +0 -73
- data/test/liquid/drop_test.rb +0 -180
- data/test/liquid/error_handling_test.rb +0 -81
- data/test/liquid/hash_ordering_test.rb +0 -25
- data/test/liquid/parsing_quirks_test.rb +0 -52
- data/test/liquid/tags/include_tag_test.rb +0 -166
- data/test/liquid/tags/statements_test.rb +0 -134
- data/test/liquid/variable_test.rb +0 -186
data/lib/liquid/tag.rb
CHANGED
@@ -1,26 +1,42 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
class Tag
|
3
|
+
attr_accessor :options, :line_number
|
4
|
+
attr_reader :nodelist, :warnings
|
5
|
+
include ParserSwitching
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def parse(tag_name, markup, tokens, options)
|
9
|
+
tag = new(tag_name, markup, options)
|
10
|
+
tag.parse(tokens)
|
11
|
+
tag
|
12
|
+
end
|
13
|
+
|
14
|
+
private :new
|
15
|
+
end
|
4
16
|
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(tag_name, markup, tokens)
|
17
|
+
def initialize(tag_name, markup, options)
|
8
18
|
@tag_name = tag_name
|
9
19
|
@markup = markup
|
10
|
-
|
20
|
+
@options = options
|
11
21
|
end
|
12
22
|
|
13
23
|
def parse(tokens)
|
14
24
|
end
|
15
25
|
|
26
|
+
def raw
|
27
|
+
"#{@tag_name} #{@markup}"
|
28
|
+
end
|
29
|
+
|
16
30
|
def name
|
17
31
|
self.class.name.downcase
|
18
32
|
end
|
19
33
|
|
20
34
|
def render(context)
|
21
|
-
''
|
35
|
+
''.freeze
|
22
36
|
end
|
23
37
|
|
24
|
-
|
25
|
-
|
26
|
-
end
|
38
|
+
def blank?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/liquid/tags/assign.rb
CHANGED
@@ -9,27 +9,30 @@ module Liquid
|
|
9
9
|
# {{ foo }}
|
10
10
|
#
|
11
11
|
class Assign < Tag
|
12
|
-
Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/
|
12
|
+
Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/om
|
13
13
|
|
14
|
-
def initialize(tag_name, markup,
|
14
|
+
def initialize(tag_name, markup, options)
|
15
|
+
super
|
15
16
|
if markup =~ Syntax
|
16
17
|
@to = $1
|
17
|
-
@from = Variable.new($2)
|
18
|
+
@from = Variable.new($2,options)
|
19
|
+
@from.line_number = line_number
|
18
20
|
else
|
19
|
-
raise SyntaxError.new("
|
21
|
+
raise SyntaxError.new options[:locale].t("errors.syntax.assign".freeze)
|
20
22
|
end
|
21
|
-
|
22
|
-
super
|
23
23
|
end
|
24
24
|
|
25
25
|
def render(context)
|
26
26
|
val = @from.render(context)
|
27
27
|
context.scopes.last[@to] = val
|
28
|
-
context.
|
29
|
-
''
|
28
|
+
context.increment_used_resources(:assign_score_current, val)
|
29
|
+
''.freeze
|
30
30
|
end
|
31
31
|
|
32
|
+
def blank?
|
33
|
+
true
|
34
|
+
end
|
32
35
|
end
|
33
36
|
|
34
|
-
Template.register_tag('assign', Assign)
|
37
|
+
Template.register_tag('assign'.freeze, Assign)
|
35
38
|
end
|
data/lib/liquid/tags/break.rb
CHANGED
data/lib/liquid/tags/capture.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# Capture stores the result of a block into a variable without rendering it inplace.
|
4
3
|
#
|
5
4
|
# {% capture heading %}
|
@@ -14,23 +13,26 @@ module Liquid
|
|
14
13
|
class Capture < Block
|
15
14
|
Syntax = /(\w+)/
|
16
15
|
|
17
|
-
def initialize(tag_name, markup,
|
16
|
+
def initialize(tag_name, markup, options)
|
17
|
+
super
|
18
18
|
if markup =~ Syntax
|
19
19
|
@to = $1
|
20
20
|
else
|
21
|
-
raise SyntaxError.new("
|
21
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.capture"))
|
22
22
|
end
|
23
|
-
|
24
|
-
super
|
25
23
|
end
|
26
24
|
|
27
25
|
def render(context)
|
28
26
|
output = super
|
29
27
|
context.scopes.last[@to] = output
|
30
|
-
context.
|
31
|
-
''
|
28
|
+
context.increment_used_resources(:assign_score_current, output)
|
29
|
+
''.freeze
|
30
|
+
end
|
31
|
+
|
32
|
+
def blank?
|
33
|
+
true
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
Template.register_tag('capture', Capture)
|
37
|
+
Template.register_tag('capture'.freeze, Capture)
|
36
38
|
end
|
data/lib/liquid/tags/case.rb
CHANGED
@@ -1,26 +1,29 @@
|
|
1
1
|
module Liquid
|
2
2
|
class Case < Block
|
3
3
|
Syntax = /(#{QuotedFragment})/o
|
4
|
-
WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/
|
4
|
+
WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/om
|
5
5
|
|
6
|
-
def initialize(tag_name, markup,
|
6
|
+
def initialize(tag_name, markup, options)
|
7
|
+
super
|
7
8
|
@blocks = []
|
8
9
|
|
9
10
|
if markup =~ Syntax
|
10
11
|
@left = $1
|
11
12
|
else
|
12
|
-
raise SyntaxError.new("
|
13
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.case".freeze))
|
13
14
|
end
|
15
|
+
end
|
14
16
|
|
15
|
-
|
17
|
+
def nodelist
|
18
|
+
@blocks.flat_map(&:attachment)
|
16
19
|
end
|
17
20
|
|
18
21
|
def unknown_tag(tag, markup, tokens)
|
19
22
|
@nodelist = []
|
20
23
|
case tag
|
21
|
-
when 'when'
|
24
|
+
when 'when'.freeze
|
22
25
|
record_when_condition(markup)
|
23
|
-
when 'else'
|
26
|
+
when 'else'.freeze
|
24
27
|
record_else_condition(markup)
|
25
28
|
else
|
26
29
|
super
|
@@ -50,30 +53,27 @@ module Liquid
|
|
50
53
|
while markup
|
51
54
|
# Create a new nodelist and assign it to the new block
|
52
55
|
if not markup =~ WhenSyntax
|
53
|
-
raise SyntaxError.new(
|
56
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_when".freeze))
|
54
57
|
end
|
55
58
|
|
56
59
|
markup = $2
|
57
60
|
|
58
|
-
block = Condition.new(@left, '==', $1)
|
61
|
+
block = Condition.new(@left, '=='.freeze, $1)
|
59
62
|
block.attach(@nodelist)
|
60
63
|
@blocks.push(block)
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
64
67
|
def record_else_condition(markup)
|
65
|
-
|
66
68
|
if not markup.strip.empty?
|
67
|
-
raise SyntaxError.new(
|
69
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_else".freeze))
|
68
70
|
end
|
69
71
|
|
70
72
|
block = ElseCondition.new
|
71
73
|
block.attach(@nodelist)
|
72
74
|
@blocks << block
|
73
75
|
end
|
74
|
-
|
75
|
-
|
76
76
|
end
|
77
77
|
|
78
|
-
Template.register_tag('case', Case)
|
78
|
+
Template.register_tag('case'.freeze, Case)
|
79
79
|
end
|
data/lib/liquid/tags/comment.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
module Liquid
|
2
2
|
class Comment < Block
|
3
3
|
def render(context)
|
4
|
-
''
|
4
|
+
''.freeze
|
5
|
+
end
|
6
|
+
|
7
|
+
def unknown_tag(tag, markup, tokens)
|
8
|
+
end
|
9
|
+
|
10
|
+
def blank?
|
11
|
+
true
|
5
12
|
end
|
6
13
|
end
|
7
14
|
|
8
|
-
Template.register_tag('comment', Comment)
|
15
|
+
Template.register_tag('comment'.freeze, Comment)
|
9
16
|
end
|
data/lib/liquid/tags/continue.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# Continue tag to be used to break out of a for loop.
|
4
3
|
#
|
5
4
|
# == Basic Usage:
|
@@ -10,12 +9,10 @@ module Liquid
|
|
10
9
|
# {% endfor %}
|
11
10
|
#
|
12
11
|
class Continue < Tag
|
13
|
-
|
14
12
|
def interrupt
|
15
13
|
ContinueInterrupt.new
|
16
14
|
end
|
17
|
-
|
18
15
|
end
|
19
16
|
|
20
|
-
Template.register_tag('continue', Continue)
|
17
|
+
Template.register_tag('continue'.freeze, Continue)
|
21
18
|
end
|
data/lib/liquid/tags/cycle.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# Cycle is usually used within a loop to alternate between values, like colors or DOM classes.
|
4
3
|
#
|
5
4
|
# {% for item in items %}
|
@@ -13,10 +12,11 @@ module Liquid
|
|
13
12
|
# <div class="green"> Item five</div>
|
14
13
|
#
|
15
14
|
class Cycle < Tag
|
16
|
-
SimpleSyntax =
|
17
|
-
NamedSyntax =
|
15
|
+
SimpleSyntax = /\A#{QuotedFragment}+/o
|
16
|
+
NamedSyntax = /\A(#{QuotedFragment})\s*\:\s*(.*)/om
|
18
17
|
|
19
|
-
def initialize(tag_name, markup,
|
18
|
+
def initialize(tag_name, markup, options)
|
19
|
+
super
|
20
20
|
case markup
|
21
21
|
when NamedSyntax
|
22
22
|
@variables = variables_from_string($2)
|
@@ -25,9 +25,8 @@ module Liquid
|
|
25
25
|
@variables = variables_from_string(markup)
|
26
26
|
@name = "'#{@variables.to_s}'"
|
27
27
|
else
|
28
|
-
raise SyntaxError.new(
|
28
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.cycle".freeze))
|
29
29
|
end
|
30
|
-
super
|
31
30
|
end
|
32
31
|
|
33
32
|
def render(context)
|
@@ -52,7 +51,6 @@ module Liquid
|
|
52
51
|
$1 ? $1 : nil
|
53
52
|
end.compact
|
54
53
|
end
|
55
|
-
|
56
54
|
end
|
57
55
|
|
58
56
|
Template.register_tag('cycle', Cycle)
|
@@ -19,10 +19,9 @@ module Liquid
|
|
19
19
|
# Hello: -3
|
20
20
|
#
|
21
21
|
class Decrement < Tag
|
22
|
-
def initialize(tag_name, markup,
|
23
|
-
@variable = markup.strip
|
24
|
-
|
22
|
+
def initialize(tag_name, markup, options)
|
25
23
|
super
|
24
|
+
@variable = markup.strip
|
26
25
|
end
|
27
26
|
|
28
27
|
def render(context)
|
@@ -35,5 +34,5 @@ module Liquid
|
|
35
34
|
private
|
36
35
|
end
|
37
36
|
|
38
|
-
Template.register_tag('decrement', Decrement)
|
37
|
+
Template.register_tag('decrement'.freeze, Decrement)
|
39
38
|
end
|
data/lib/liquid/tags/for.rb
CHANGED
@@ -44,28 +44,24 @@ module Liquid
|
|
44
44
|
# forloop.last:: Returns true if the item is the last item.
|
45
45
|
#
|
46
46
|
class For < Block
|
47
|
-
Syntax = /\A(
|
47
|
+
Syntax = /\A(#{VariableSegment}+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o
|
48
48
|
|
49
|
-
def initialize(tag_name, markup,
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
49
|
+
def initialize(tag_name, markup, options)
|
50
|
+
super
|
51
|
+
parse_with_selected_parser(markup)
|
52
|
+
@nodelist = @for_block = []
|
53
|
+
end
|
54
|
+
|
55
|
+
def nodelist
|
56
|
+
if @else_block
|
57
|
+
@for_block + @else_block
|
59
58
|
else
|
60
|
-
|
59
|
+
@for_block
|
61
60
|
end
|
62
|
-
|
63
|
-
@nodelist = @for_block = []
|
64
|
-
super
|
65
61
|
end
|
66
62
|
|
67
63
|
def unknown_tag(tag, markup, tokens)
|
68
|
-
return super unless tag == 'else'
|
64
|
+
return super unless tag == 'else'.freeze
|
69
65
|
@nodelist = @else_block = []
|
70
66
|
end
|
71
67
|
|
@@ -78,17 +74,16 @@ module Liquid
|
|
78
74
|
# Maintains Ruby 1.8.7 String#each behaviour on 1.9
|
79
75
|
return render_else(context) unless iterable?(collection)
|
80
76
|
|
81
|
-
from = if @attributes['offset'] == 'continue'
|
77
|
+
from = if @attributes['offset'.freeze] == 'continue'.freeze
|
82
78
|
context.registers[:for][@name].to_i
|
83
79
|
else
|
84
|
-
context[@attributes['offset']].to_i
|
80
|
+
context[@attributes['offset'.freeze]].to_i
|
85
81
|
end
|
86
82
|
|
87
|
-
limit = context[@attributes['limit']]
|
83
|
+
limit = context[@attributes['limit'.freeze]]
|
88
84
|
to = limit ? limit.to_i + from : nil
|
89
85
|
|
90
|
-
|
91
|
-
segment = Utils.slice_collection_using_each(collection, from, to)
|
86
|
+
segment = Utils.slice_collection(collection, from, to)
|
92
87
|
|
93
88
|
return render_else(context) if segment.empty?
|
94
89
|
|
@@ -104,15 +99,16 @@ module Liquid
|
|
104
99
|
context.stack do
|
105
100
|
segment.each_with_index do |item, index|
|
106
101
|
context[@variable_name] = item
|
107
|
-
context['forloop'] = {
|
108
|
-
'name' => @name,
|
109
|
-
'length' => length,
|
110
|
-
'index' => index + 1,
|
111
|
-
'index0' => index,
|
112
|
-
'rindex' => length - index,
|
113
|
-
'rindex0' => length - index - 1,
|
114
|
-
'first' => (index == 0),
|
115
|
-
|
102
|
+
context['forloop'.freeze] = {
|
103
|
+
'name'.freeze => @name,
|
104
|
+
'length'.freeze => length,
|
105
|
+
'index'.freeze => index + 1,
|
106
|
+
'index0'.freeze => index,
|
107
|
+
'rindex'.freeze => length - index,
|
108
|
+
'rindex0'.freeze => length - index - 1,
|
109
|
+
'first'.freeze => (index == 0),
|
110
|
+
'last'.freeze => (index == length - 1)
|
111
|
+
}
|
116
112
|
|
117
113
|
result << render_all(@for_block, context)
|
118
114
|
|
@@ -127,16 +123,53 @@ module Liquid
|
|
127
123
|
result
|
128
124
|
end
|
129
125
|
|
130
|
-
|
126
|
+
protected
|
131
127
|
|
132
|
-
|
133
|
-
|
128
|
+
def lax_parse(markup)
|
129
|
+
if markup =~ Syntax
|
130
|
+
@variable_name = $1
|
131
|
+
@collection_name = $2
|
132
|
+
@name = "#{$1}-#{$2}"
|
133
|
+
@reversed = $3
|
134
|
+
@attributes = {}
|
135
|
+
markup.scan(TagAttributes) do |key, value|
|
136
|
+
@attributes[key] = value
|
137
|
+
end
|
138
|
+
else
|
139
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.for".freeze))
|
134
140
|
end
|
141
|
+
end
|
135
142
|
|
136
|
-
|
137
|
-
|
143
|
+
def strict_parse(markup)
|
144
|
+
p = Parser.new(markup)
|
145
|
+
@variable_name = p.consume(:id)
|
146
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_in".freeze)) unless p.id?('in'.freeze)
|
147
|
+
@collection_name = p.expression
|
148
|
+
@name = "#{@variable_name}-#{@collection_name}"
|
149
|
+
@reversed = p.id?('reversed'.freeze)
|
150
|
+
|
151
|
+
@attributes = {}
|
152
|
+
while p.look(:id) && p.look(:colon, 1)
|
153
|
+
unless attribute = p.id?('limit'.freeze) || p.id?('offset'.freeze)
|
154
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_attribute".freeze))
|
155
|
+
end
|
156
|
+
p.consume
|
157
|
+
val = p.expression
|
158
|
+
@attributes[attribute] = val
|
138
159
|
end
|
160
|
+
p.consume(:end_of_string)
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def render_else(context)
|
166
|
+
return @else_block ? [render_all(@else_block, context)] : ''.freeze
|
167
|
+
end
|
168
|
+
|
169
|
+
def iterable?(collection)
|
170
|
+
collection.respond_to?(:each) || Utils.non_blank_string?(collection)
|
171
|
+
end
|
139
172
|
end
|
140
173
|
|
141
|
-
Template.register_tag('for', For)
|
174
|
+
Template.register_tag('for'.freeze, For)
|
142
175
|
end
|
data/lib/liquid/tags/if.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# If is the conditional block
|
4
3
|
#
|
5
4
|
# {% if user.admin %}
|
@@ -10,23 +9,23 @@ module Liquid
|
|
10
9
|
#
|
11
10
|
# There are {% if count < 5 %} less {% else %} more {% endif %} items than you need.
|
12
11
|
#
|
13
|
-
#
|
14
12
|
class If < Block
|
15
|
-
SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
16
13
|
Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/o
|
17
14
|
ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o
|
18
15
|
BOOLEAN_OPERATORS = %w(and or)
|
19
16
|
|
20
|
-
def initialize(tag_name, markup,
|
17
|
+
def initialize(tag_name, markup, options)
|
18
|
+
super
|
21
19
|
@blocks = []
|
20
|
+
push_block('if'.freeze, markup)
|
21
|
+
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
super
|
23
|
+
def nodelist
|
24
|
+
@blocks.flat_map(&:attachment)
|
26
25
|
end
|
27
26
|
|
28
27
|
def unknown_tag(tag, markup, tokens)
|
29
|
-
if ['elsif', 'else'].include?(tag)
|
28
|
+
if ['elsif'.freeze, 'else'.freeze].include?(tag)
|
30
29
|
push_block(tag, markup)
|
31
30
|
else
|
32
31
|
super
|
@@ -40,40 +39,68 @@ module Liquid
|
|
40
39
|
return render_all(block.attachment, context)
|
41
40
|
end
|
42
41
|
end
|
43
|
-
''
|
42
|
+
''.freeze
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
46
|
private
|
48
47
|
|
49
48
|
def push_block(tag, markup)
|
50
|
-
block = if tag == 'else'
|
49
|
+
block = if tag == 'else'.freeze
|
51
50
|
ElseCondition.new
|
52
51
|
else
|
52
|
+
parse_with_selected_parser(markup)
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
@blocks.push(block)
|
56
|
+
@nodelist = block.attach(Array.new)
|
57
|
+
end
|
56
58
|
|
57
|
-
|
59
|
+
def lax_parse(markup)
|
60
|
+
expressions = markup.scan(ExpressionsAndOperators)
|
61
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop =~ Syntax
|
58
62
|
|
59
|
-
|
60
|
-
operator = (expressions.shift).to_s.strip
|
63
|
+
condition = Condition.new($1, $2, $3)
|
61
64
|
|
62
|
-
|
65
|
+
while not expressions.empty?
|
66
|
+
operator = expressions.pop.to_s.strip
|
63
67
|
|
64
|
-
|
65
|
-
raise SyntaxError, "invalid boolean operator" unless BOOLEAN_OPERATORS.include?(operator)
|
66
|
-
new_condition.send(operator, condition)
|
67
|
-
condition = new_condition
|
68
|
-
end
|
68
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop.to_s =~ Syntax
|
69
69
|
|
70
|
-
|
70
|
+
new_condition = Condition.new($1, $2, $3)
|
71
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator)
|
72
|
+
new_condition.send(operator, condition)
|
73
|
+
condition = new_condition
|
71
74
|
end
|
72
75
|
|
73
|
-
|
74
|
-
|
76
|
+
condition
|
77
|
+
end
|
78
|
+
|
79
|
+
def strict_parse(markup)
|
80
|
+
p = Parser.new(markup)
|
81
|
+
|
82
|
+
condition = parse_comparison(p)
|
83
|
+
|
84
|
+
while op = (p.id?('and'.freeze) || p.id?('or'.freeze))
|
85
|
+
new_cond = parse_comparison(p)
|
86
|
+
new_cond.send(op, condition)
|
87
|
+
condition = new_cond
|
88
|
+
end
|
89
|
+
p.consume(:end_of_string)
|
90
|
+
|
91
|
+
condition
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_comparison(p)
|
95
|
+
a = p.expression
|
96
|
+
if op = p.consume?(:comparison)
|
97
|
+
b = p.expression
|
98
|
+
Condition.new(a, op, b)
|
99
|
+
else
|
100
|
+
Condition.new(a)
|
101
|
+
end
|
75
102
|
end
|
76
103
|
end
|
77
104
|
|
78
|
-
Template.register_tag('if', If)
|
105
|
+
Template.register_tag('if'.freeze, If)
|
79
106
|
end
|
@@ -4,17 +4,17 @@ module Liquid
|
|
4
4
|
def render(context)
|
5
5
|
context.stack do
|
6
6
|
|
7
|
-
output =
|
7
|
+
output = super
|
8
8
|
|
9
9
|
if output != context.registers[:ifchanged]
|
10
10
|
context.registers[:ifchanged] = output
|
11
11
|
output
|
12
12
|
else
|
13
|
-
''
|
13
|
+
''.freeze
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
Template.register_tag('ifchanged', Ifchanged)
|
19
|
+
Template.register_tag('ifchanged'.freeze, Ifchanged)
|
20
20
|
end
|
data/lib/liquid/tags/include.rb
CHANGED
@@ -17,7 +17,9 @@ module Liquid
|
|
17
17
|
class Include < Tag
|
18
18
|
Syntax = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?/o
|
19
19
|
|
20
|
-
def initialize(tag_name, markup,
|
20
|
+
def initialize(tag_name, markup, options)
|
21
|
+
super
|
22
|
+
|
21
23
|
if markup =~ Syntax
|
22
24
|
|
23
25
|
@template_name = $1
|
@@ -29,10 +31,8 @@ module Liquid
|
|
29
31
|
end
|
30
32
|
|
31
33
|
else
|
32
|
-
raise SyntaxError.new(
|
34
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.include".freeze))
|
33
35
|
end
|
34
|
-
|
35
|
-
super
|
36
36
|
end
|
37
37
|
|
38
38
|
def parse(tokens)
|
@@ -47,13 +47,14 @@ module Liquid
|
|
47
47
|
context[key] = context[value]
|
48
48
|
end
|
49
49
|
|
50
|
+
context_variable_name = @template_name[1..-2].split('/'.freeze).last
|
50
51
|
if variable.is_a?(Array)
|
51
52
|
variable.collect do |var|
|
52
|
-
context[
|
53
|
+
context[context_variable_name] = var
|
53
54
|
partial.render(context)
|
54
55
|
end
|
55
56
|
else
|
56
|
-
context[
|
57
|
+
context[context_variable_name] = variable
|
57
58
|
partial.render(context)
|
58
59
|
end
|
59
60
|
end
|
@@ -68,7 +69,7 @@ module Liquid
|
|
68
69
|
return cached
|
69
70
|
end
|
70
71
|
source = read_template_from_file_system(context)
|
71
|
-
partial = Liquid::Template.parse(source)
|
72
|
+
partial = Liquid::Template.parse(source, pass_options)
|
72
73
|
cached_partials[template_name] = partial
|
73
74
|
context.registers[:cached_partials] = cached_partials
|
74
75
|
partial
|
@@ -87,7 +88,17 @@ module Liquid
|
|
87
88
|
raise ArgumentError, "file_system.read_template_file expects two parameters: (template_name, context)"
|
88
89
|
end
|
89
90
|
end
|
91
|
+
|
92
|
+
def pass_options
|
93
|
+
dont_pass = @options[:include_options_blacklist]
|
94
|
+
return {locale: @options[:locale]} if dont_pass == true
|
95
|
+
opts = @options.merge(included: true, include_options_blacklist: false)
|
96
|
+
if dont_pass.is_a?(Array)
|
97
|
+
dont_pass.each {|o| opts.delete(o)}
|
98
|
+
end
|
99
|
+
opts
|
100
|
+
end
|
90
101
|
end
|
91
102
|
|
92
|
-
Template.register_tag('include', Include)
|
103
|
+
Template.register_tag('include'.freeze, Include)
|
93
104
|
end
|