liquid 3.0.0 → 4.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 +130 -62
- data/README.md +31 -0
- data/lib/liquid/block.rb +31 -124
- data/lib/liquid/block_body.rb +75 -59
- data/lib/liquid/condition.rb +23 -22
- data/lib/liquid/context.rb +51 -60
- data/lib/liquid/document.rb +19 -9
- data/lib/liquid/drop.rb +17 -16
- data/lib/liquid/errors.rb +20 -24
- data/lib/liquid/expression.rb +15 -3
- data/lib/liquid/extensions.rb +13 -7
- data/lib/liquid/file_system.rb +11 -11
- 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 +5 -1
- data/lib/liquid/parse_context.rb +37 -0
- data/lib/liquid/parser.rb +1 -1
- data/lib/liquid/parser_switching.rb +4 -4
- data/lib/liquid/profiler/hooks.rb +7 -7
- data/lib/liquid/profiler.rb +18 -19
- data/lib/liquid/range_lookup.rb +16 -1
- data/lib/liquid/resource_limits.rb +23 -0
- data/lib/liquid/standardfilters.rb +121 -61
- data/lib/liquid/strainer.rb +32 -29
- data/lib/liquid/tablerowloop_drop.rb +62 -0
- data/lib/liquid/tag.rb +9 -8
- data/lib/liquid/tags/assign.rb +17 -4
- data/lib/liquid/tags/break.rb +0 -3
- data/lib/liquid/tags/capture.rb +2 -2
- 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 +95 -75
- data/lib/liquid/tags/if.rb +48 -43
- data/lib/liquid/tags/ifchanged.rb +0 -2
- data/lib/liquid/tags/include.rb +61 -52
- data/lib/liquid/tags/raw.rb +32 -4
- data/lib/liquid/tags/table_row.rb +12 -31
- data/lib/liquid/tags/unless.rb +4 -5
- data/lib/liquid/template.rb +42 -54
- data/lib/liquid/tokenizer.rb +31 -0
- data/lib/liquid/utils.rb +52 -8
- data/lib/liquid/variable.rb +46 -45
- data/lib/liquid/variable_lookup.rb +9 -5
- data/lib/liquid/version.rb +1 -1
- data/lib/liquid.rb +9 -7
- data/test/integration/assign_test.rb +18 -8
- data/test/integration/blank_test.rb +14 -14
- data/test/integration/capture_test.rb +10 -0
- 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 +99 -46
- data/test/integration/filter_test.rb +72 -19
- data/test/integration/hash_ordering_test.rb +9 -9
- data/test/integration/output_test.rb +34 -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 +9 -7
- data/test/integration/standard_filter_test.rb +198 -42
- 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 +96 -77
- data/test/integration/tags/include_tag_test.rb +34 -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 +190 -49
- data/test/integration/trim_mode_test.rb +525 -0
- data/test/integration/variable_test.rb +23 -13
- data/test/test_helper.rb +44 -9
- data/test/unit/block_unit_test.rb +8 -5
- data/test/unit/condition_unit_test.rb +86 -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 +85 -8
- 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 +14 -5
- data/test/unit/tokenizer_unit_test.rb +24 -7
- data/test/unit/variable_unit_test.rb +66 -43
- metadata +55 -50
- 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
- /data/{MIT-LICENSE → LICENSE} +0 -0
data/lib/liquid/tags/cycle.rb
CHANGED
@@ -20,10 +20,10 @@ module Liquid
|
|
20
20
|
case markup
|
21
21
|
when NamedSyntax
|
22
22
|
@variables = variables_from_string($2)
|
23
|
-
@name = $1
|
23
|
+
@name = Expression.parse($1)
|
24
24
|
when SimpleSyntax
|
25
25
|
@variables = variables_from_string(markup)
|
26
|
-
@name =
|
26
|
+
@name = @variables.to_s
|
27
27
|
else
|
28
28
|
raise SyntaxError.new(options[:locale].t("errors.syntax.cycle".freeze))
|
29
29
|
end
|
@@ -33,11 +33,11 @@ module Liquid
|
|
33
33
|
context.registers[:cycle] ||= Hash.new(0)
|
34
34
|
|
35
35
|
context.stack do
|
36
|
-
key = context
|
36
|
+
key = context.evaluate(@name)
|
37
37
|
iteration = context.registers[:cycle][key]
|
38
|
-
result = context
|
38
|
+
result = context.evaluate(@variables[iteration])
|
39
39
|
iteration += 1
|
40
|
-
iteration = 0
|
40
|
+
iteration = 0 if iteration >= @variables.size
|
41
41
|
context.registers[:cycle][key] = iteration
|
42
42
|
result
|
43
43
|
end
|
@@ -48,7 +48,7 @@ module Liquid
|
|
48
48
|
def variables_from_string(markup)
|
49
49
|
markup.split(',').collect do |var|
|
50
50
|
var =~ /\s*(#{QuotedFragment})\s*/o
|
51
|
-
$1 ? $1 : nil
|
51
|
+
$1 ? Expression.parse($1) : nil
|
52
52
|
end.compact
|
53
53
|
end
|
54
54
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# decrement is used in a place where one needs to insert a counter
|
4
3
|
# into a template, and needs the counter to survive across
|
5
4
|
# multiple instantiations of the template.
|
@@ -26,12 +25,10 @@ module Liquid
|
|
26
25
|
|
27
26
|
def render(context)
|
28
27
|
value = context.environments.first[@variable] ||= 0
|
29
|
-
value
|
28
|
+
value -= 1
|
30
29
|
context.environments.first[@variable] = value
|
31
30
|
value.to_s
|
32
31
|
end
|
33
|
-
|
34
|
-
private
|
35
32
|
end
|
36
33
|
|
37
34
|
Template.register_tag('decrement'.freeze, Decrement)
|
data/lib/liquid/tags/for.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# "For" iterates over an array or collection.
|
4
3
|
# Several useful variables are available to you within the loop.
|
5
4
|
#
|
@@ -42,85 +41,41 @@ module Liquid
|
|
42
41
|
# where 0 is the last item.
|
43
42
|
# forloop.first:: Returns true if the item is the first item.
|
44
43
|
# forloop.last:: Returns true if the item is the last item.
|
44
|
+
# forloop.parentloop:: Provides access to the parent loop, if present.
|
45
45
|
#
|
46
46
|
class For < Block
|
47
47
|
Syntax = /\A(#{VariableSegment}+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o
|
48
48
|
|
49
49
|
def initialize(tag_name, markup, options)
|
50
50
|
super
|
51
|
+
@from = @limit = nil
|
51
52
|
parse_with_selected_parser(markup)
|
52
|
-
@
|
53
|
+
@for_block = BlockBody.new
|
54
|
+
@else_block = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def parse(tokens)
|
58
|
+
return unless parse_body(@for_block, tokens)
|
59
|
+
parse_body(@else_block, tokens)
|
53
60
|
end
|
54
61
|
|
55
62
|
def nodelist
|
56
|
-
|
57
|
-
@for_block + @else_block
|
58
|
-
else
|
59
|
-
@for_block
|
60
|
-
end
|
63
|
+
@else_block ? [@for_block, @else_block] : [@for_block]
|
61
64
|
end
|
62
65
|
|
63
66
|
def unknown_tag(tag, markup, tokens)
|
64
67
|
return super unless tag == 'else'.freeze
|
65
|
-
@
|
68
|
+
@else_block = BlockBody.new
|
66
69
|
end
|
67
70
|
|
68
71
|
def render(context)
|
69
|
-
|
70
|
-
|
71
|
-
collection = context[@collection_name]
|
72
|
-
collection = collection.to_a if collection.is_a?(Range)
|
73
|
-
|
74
|
-
# Maintains Ruby 1.8.7 String#each behaviour on 1.9
|
75
|
-
return render_else(context) unless iterable?(collection)
|
72
|
+
segment = collection_segment(context)
|
76
73
|
|
77
|
-
|
78
|
-
context
|
74
|
+
if segment.empty?
|
75
|
+
render_else(context)
|
79
76
|
else
|
80
|
-
context
|
77
|
+
render_segment(context, segment)
|
81
78
|
end
|
82
|
-
|
83
|
-
limit = context[@attributes['limit'.freeze]]
|
84
|
-
to = limit ? limit.to_i + from : nil
|
85
|
-
|
86
|
-
segment = Utils.slice_collection(collection, from, to)
|
87
|
-
|
88
|
-
return render_else(context) if segment.empty?
|
89
|
-
|
90
|
-
segment.reverse! if @reversed
|
91
|
-
|
92
|
-
result = ''
|
93
|
-
|
94
|
-
length = segment.length
|
95
|
-
|
96
|
-
# Store our progress through the collection for the continue flag
|
97
|
-
context.registers[:for][@name] = from + segment.length
|
98
|
-
|
99
|
-
context.stack do
|
100
|
-
segment.each_with_index do |item, index|
|
101
|
-
context[@variable_name] = item
|
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
|
-
}
|
112
|
-
|
113
|
-
result << render_all(@for_block, context)
|
114
|
-
|
115
|
-
# Handle any interrupts if they exist.
|
116
|
-
if context.has_interrupt?
|
117
|
-
interrupt = context.pop_interrupt
|
118
|
-
break if interrupt.is_a? BreakInterrupt
|
119
|
-
next if interrupt.is_a? ContinueInterrupt
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
result
|
124
79
|
end
|
125
80
|
|
126
81
|
protected
|
@@ -128,12 +83,12 @@ module Liquid
|
|
128
83
|
def lax_parse(markup)
|
129
84
|
if markup =~ Syntax
|
130
85
|
@variable_name = $1
|
131
|
-
|
132
|
-
@
|
133
|
-
@
|
134
|
-
@
|
86
|
+
collection_name = $2
|
87
|
+
@reversed = !!$3
|
88
|
+
@name = "#{@variable_name}-#{collection_name}"
|
89
|
+
@collection_name = Expression.parse(collection_name)
|
135
90
|
markup.scan(TagAttributes) do |key, value|
|
136
|
-
|
91
|
+
set_attribute(key, value)
|
137
92
|
end
|
138
93
|
else
|
139
94
|
raise SyntaxError.new(options[:locale].t("errors.syntax.for".freeze))
|
@@ -143,31 +98,96 @@ module Liquid
|
|
143
98
|
def strict_parse(markup)
|
144
99
|
p = Parser.new(markup)
|
145
100
|
@variable_name = p.consume(:id)
|
146
|
-
raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_in".freeze))
|
147
|
-
|
148
|
-
@name = "#{@variable_name}-#{
|
101
|
+
raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_in".freeze)) unless p.id?('in'.freeze)
|
102
|
+
collection_name = p.expression
|
103
|
+
@name = "#{@variable_name}-#{collection_name}"
|
104
|
+
@collection_name = Expression.parse(collection_name)
|
149
105
|
@reversed = p.id?('reversed'.freeze)
|
150
106
|
|
151
|
-
@attributes = {}
|
152
107
|
while p.look(:id) && p.look(:colon, 1)
|
153
108
|
unless attribute = p.id?('limit'.freeze) || p.id?('offset'.freeze)
|
154
109
|
raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_attribute".freeze))
|
155
110
|
end
|
156
111
|
p.consume
|
157
|
-
|
158
|
-
@attributes[attribute] = val
|
112
|
+
set_attribute(attribute, p.expression)
|
159
113
|
end
|
160
114
|
p.consume(:end_of_string)
|
161
115
|
end
|
162
116
|
|
163
117
|
private
|
164
118
|
|
165
|
-
def
|
166
|
-
|
119
|
+
def collection_segment(context)
|
120
|
+
offsets = context.registers[:for] ||= Hash.new(0)
|
121
|
+
|
122
|
+
from = if @from == :continue
|
123
|
+
offsets[@name].to_i
|
124
|
+
else
|
125
|
+
context.evaluate(@from).to_i
|
126
|
+
end
|
127
|
+
|
128
|
+
collection = context.evaluate(@collection_name)
|
129
|
+
collection = collection.to_a if collection.is_a?(Range)
|
130
|
+
|
131
|
+
limit = context.evaluate(@limit)
|
132
|
+
to = limit ? limit.to_i + from : nil
|
133
|
+
|
134
|
+
segment = Utils.slice_collection(collection, from, to)
|
135
|
+
segment.reverse! if @reversed
|
136
|
+
|
137
|
+
offsets[@name] = from + segment.length
|
138
|
+
|
139
|
+
segment
|
167
140
|
end
|
168
141
|
|
169
|
-
def
|
170
|
-
|
142
|
+
def render_segment(context, segment)
|
143
|
+
for_stack = context.registers[:for_stack] ||= []
|
144
|
+
length = segment.length
|
145
|
+
|
146
|
+
result = ''
|
147
|
+
|
148
|
+
context.stack do
|
149
|
+
loop_vars = Liquid::ForloopDrop.new(@name, length, for_stack[-1])
|
150
|
+
|
151
|
+
for_stack.push(loop_vars)
|
152
|
+
|
153
|
+
begin
|
154
|
+
context['forloop'.freeze] = loop_vars
|
155
|
+
|
156
|
+
segment.each_with_index do |item, index|
|
157
|
+
context[@variable_name] = item
|
158
|
+
result << @for_block.render(context)
|
159
|
+
loop_vars.send(:increment!)
|
160
|
+
|
161
|
+
# Handle any interrupts if they exist.
|
162
|
+
if context.interrupt?
|
163
|
+
interrupt = context.pop_interrupt
|
164
|
+
break if interrupt.is_a? BreakInterrupt
|
165
|
+
next if interrupt.is_a? ContinueInterrupt
|
166
|
+
end
|
167
|
+
end
|
168
|
+
ensure
|
169
|
+
for_stack.pop
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
result
|
174
|
+
end
|
175
|
+
|
176
|
+
def set_attribute(key, expr)
|
177
|
+
case key
|
178
|
+
when 'offset'.freeze
|
179
|
+
@from = if expr == 'continue'.freeze
|
180
|
+
:continue
|
181
|
+
else
|
182
|
+
Expression.parse(expr)
|
183
|
+
end
|
184
|
+
when 'limit'.freeze
|
185
|
+
@limit = Expression.parse(expr)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def render_else(context)
|
190
|
+
@else_block ? @else_block.render(context) : ''.freeze
|
171
191
|
end
|
172
192
|
end
|
173
193
|
|
data/lib/liquid/tags/if.rb
CHANGED
@@ -20,8 +20,13 @@ module Liquid
|
|
20
20
|
push_block('if'.freeze, markup)
|
21
21
|
end
|
22
22
|
|
23
|
+
def parse(tokens)
|
24
|
+
while parse_body(@blocks.last.attachment, tokens)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
23
28
|
def nodelist
|
24
|
-
@blocks.
|
29
|
+
@blocks.map(&:attachment)
|
25
30
|
end
|
26
31
|
|
27
32
|
def unknown_tag(tag, markup, tokens)
|
@@ -36,7 +41,7 @@ module Liquid
|
|
36
41
|
context.stack do
|
37
42
|
@blocks.each do |block|
|
38
43
|
if block.evaluate(context)
|
39
|
-
return
|
44
|
+
return block.attachment.render(context)
|
40
45
|
end
|
41
46
|
end
|
42
47
|
''.freeze
|
@@ -45,61 +50,61 @@ module Liquid
|
|
45
50
|
|
46
51
|
private
|
47
52
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
@blocks.push(block)
|
56
|
-
@nodelist = block.attach(Array.new)
|
53
|
+
def push_block(tag, markup)
|
54
|
+
block = if tag == 'else'.freeze
|
55
|
+
ElseCondition.new
|
56
|
+
else
|
57
|
+
parse_with_selected_parser(markup)
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
@blocks.push(block)
|
61
|
+
block.attach(BlockBody.new)
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
+
def lax_parse(markup)
|
65
|
+
expressions = markup.scan(ExpressionsAndOperators)
|
66
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop =~ Syntax
|
64
67
|
|
65
|
-
|
66
|
-
operator = expressions.pop.to_s.strip
|
68
|
+
condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
|
67
69
|
|
68
|
-
|
70
|
+
until expressions.empty?
|
71
|
+
operator = expressions.pop.to_s.strip
|
69
72
|
|
70
|
-
|
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
|
74
|
-
end
|
73
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless expressions.pop.to_s =~ Syntax
|
75
74
|
|
76
|
-
|
75
|
+
new_condition = Condition.new(Expression.parse($1), $2, Expression.parse($3))
|
76
|
+
raise(SyntaxError.new(options[:locale].t("errors.syntax.if".freeze))) unless BOOLEAN_OPERATORS.include?(operator)
|
77
|
+
new_condition.send(operator, condition)
|
78
|
+
condition = new_condition
|
77
79
|
end
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
condition = parse_comparison(p)
|
81
|
+
condition
|
82
|
+
end
|
83
83
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
84
|
+
def strict_parse(markup)
|
85
|
+
p = Parser.new(markup)
|
86
|
+
condition = parse_binary_comparison(p)
|
87
|
+
p.consume(:end_of_string)
|
88
|
+
condition
|
89
|
+
end
|
90
90
|
|
91
|
-
|
91
|
+
def parse_binary_comparison(p)
|
92
|
+
condition = parse_comparison(p)
|
93
|
+
if op = (p.id?('and'.freeze) || p.id?('or'.freeze))
|
94
|
+
condition.send(op, parse_binary_comparison(p))
|
92
95
|
end
|
96
|
+
condition
|
97
|
+
end
|
93
98
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
99
|
+
def parse_comparison(p)
|
100
|
+
a = Expression.parse(p.expression)
|
101
|
+
if op = p.consume?(:comparison)
|
102
|
+
b = Expression.parse(p.expression)
|
103
|
+
Condition.new(a, op, b)
|
104
|
+
else
|
105
|
+
Condition.new(a)
|
102
106
|
end
|
107
|
+
end
|
103
108
|
end
|
104
109
|
|
105
110
|
Template.register_tag('if'.freeze, If)
|
data/lib/liquid/tags/include.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
3
2
|
# Include allows templates to relate with other templates
|
4
3
|
#
|
5
4
|
# Simply include another template:
|
@@ -22,12 +21,15 @@ module Liquid
|
|
22
21
|
|
23
22
|
if markup =~ Syntax
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
template_name = $1
|
25
|
+
variable_name = $3
|
26
|
+
|
27
|
+
@variable_name_expr = variable_name ? Expression.parse(variable_name) : nil
|
28
|
+
@template_name_expr = Expression.parse(template_name)
|
29
|
+
@attributes = {}
|
28
30
|
|
29
31
|
markup.scan(TagAttributes) do |key, value|
|
30
|
-
@attributes[key] = value
|
32
|
+
@attributes[key] = Expression.parse(value)
|
31
33
|
end
|
32
34
|
|
33
35
|
else
|
@@ -35,69 +37,76 @@ module Liquid
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
def parse(
|
40
|
+
def parse(_tokens)
|
39
41
|
end
|
40
42
|
|
41
43
|
def render(context)
|
42
|
-
|
43
|
-
|
44
|
+
template_name = context.evaluate(@template_name_expr)
|
45
|
+
raise ArgumentError.new(options[:locale].t("errors.argument.include")) unless template_name
|
44
46
|
|
45
|
-
context
|
46
|
-
|
47
|
-
context[key] = context[value]
|
48
|
-
end
|
47
|
+
partial = load_cached_partial(template_name, context)
|
48
|
+
context_variable_name = template_name.split('/'.freeze).last
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
variable = if @variable_name_expr
|
51
|
+
context.evaluate(@variable_name_expr)
|
52
|
+
else
|
53
|
+
context.find_variable(template_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
old_template_name = context.template_name
|
57
|
+
old_partial = context.partial
|
58
|
+
begin
|
59
|
+
context.template_name = template_name
|
60
|
+
context.partial = true
|
61
|
+
context.stack do
|
62
|
+
@attributes.each do |key, value|
|
63
|
+
context[key] = context.evaluate(value)
|
64
|
+
end
|
65
|
+
|
66
|
+
if variable.is_a?(Array)
|
67
|
+
variable.collect do |var|
|
68
|
+
context[context_variable_name] = var
|
69
|
+
partial.render(context)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
context[context_variable_name] = variable
|
54
73
|
partial.render(context)
|
55
74
|
end
|
56
|
-
else
|
57
|
-
context[context_variable_name] = variable
|
58
|
-
partial.render(context)
|
59
75
|
end
|
76
|
+
ensure
|
77
|
+
context.template_name = old_template_name
|
78
|
+
context.partial = old_partial
|
60
79
|
end
|
61
80
|
end
|
62
81
|
|
63
82
|
private
|
64
|
-
def load_cached_partial(context)
|
65
|
-
cached_partials = context.registers[:cached_partials] || {}
|
66
|
-
template_name = context[@template_name]
|
67
83
|
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
source = read_template_from_file_system(context)
|
72
|
-
partial = Liquid::Template.parse(source, pass_options)
|
73
|
-
cached_partials[template_name] = partial
|
74
|
-
context.registers[:cached_partials] = cached_partials
|
75
|
-
partial
|
76
|
-
end
|
84
|
+
alias_method :parse_context, :options
|
85
|
+
private :parse_context
|
77
86
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
# make read_template_file call backwards-compatible.
|
82
|
-
case file_system.method(:read_template_file).arity
|
83
|
-
when 1
|
84
|
-
file_system.read_template_file(context[@template_name])
|
85
|
-
when 2
|
86
|
-
file_system.read_template_file(context[@template_name], context)
|
87
|
-
else
|
88
|
-
raise ArgumentError, "file_system.read_template_file expects two parameters: (template_name, context)"
|
89
|
-
end
|
90
|
-
end
|
87
|
+
def load_cached_partial(template_name, context)
|
88
|
+
cached_partials = context.registers[:cached_partials] || {}
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
90
|
+
if cached = cached_partials[template_name]
|
91
|
+
return cached
|
92
|
+
end
|
93
|
+
source = read_template_from_file_system(context)
|
94
|
+
begin
|
95
|
+
parse_context.partial = true
|
96
|
+
partial = Liquid::Template.parse(source, parse_context)
|
97
|
+
ensure
|
98
|
+
parse_context.partial = false
|
100
99
|
end
|
100
|
+
cached_partials[template_name] = partial
|
101
|
+
context.registers[:cached_partials] = cached_partials
|
102
|
+
partial
|
103
|
+
end
|
104
|
+
|
105
|
+
def read_template_from_file_system(context)
|
106
|
+
file_system = context.registers[:file_system] || Liquid::Template.file_system
|
107
|
+
|
108
|
+
file_system.read_template_file(context.evaluate(@template_name_expr))
|
109
|
+
end
|
101
110
|
end
|
102
111
|
|
103
112
|
Template.register_tag('include'.freeze, Include)
|
data/lib/liquid/tags/raw.rb
CHANGED
@@ -1,16 +1,44 @@
|
|
1
1
|
module Liquid
|
2
2
|
class Raw < Block
|
3
|
+
Syntax = /\A\s*\z/
|
3
4
|
FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om
|
4
5
|
|
6
|
+
def initialize(tag_name, markup, parse_context)
|
7
|
+
super
|
8
|
+
|
9
|
+
ensure_valid_markup(tag_name, markup, parse_context)
|
10
|
+
end
|
11
|
+
|
5
12
|
def parse(tokens)
|
6
|
-
@
|
7
|
-
@nodelist.clear
|
13
|
+
@body = ''
|
8
14
|
while token = tokens.shift
|
9
15
|
if token =~ FullTokenPossiblyInvalid
|
10
|
-
@
|
16
|
+
@body << $1 if $1 != "".freeze
|
11
17
|
return if block_delimiter == $2
|
12
18
|
end
|
13
|
-
@
|
19
|
+
@body << token unless token.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_never_closed".freeze, block_name: block_name))
|
23
|
+
end
|
24
|
+
|
25
|
+
def render(_context)
|
26
|
+
@body
|
27
|
+
end
|
28
|
+
|
29
|
+
def nodelist
|
30
|
+
[@body]
|
31
|
+
end
|
32
|
+
|
33
|
+
def blank?
|
34
|
+
@body.empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def ensure_valid_markup(tag_name, markup, parse_context)
|
40
|
+
unless markup =~ Syntax
|
41
|
+
raise SyntaxError.new(parse_context.locale.t("errors.syntax.tag_unexpected_args".freeze, tag: tag_name))
|
14
42
|
end
|
15
43
|
end
|
16
44
|
end
|