liquid 2.5.5 → 2.6.0.rc1
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 +13 -5
- data/History.md +26 -11
- data/MIT-LICENSE +1 -1
- data/README.md +6 -0
- data/lib/extras/liquid_view.rb +9 -9
- data/lib/liquid.rb +1 -0
- data/lib/liquid/block.rb +16 -5
- data/lib/liquid/context.rb +17 -9
- data/lib/liquid/document.rb +1 -1
- data/lib/liquid/errors.rb +2 -1
- data/lib/liquid/file_system.rb +12 -12
- data/lib/liquid/htmltags.rb +1 -1
- data/lib/liquid/module_ex.rb +1 -1
- data/lib/liquid/standardfilters.rb +44 -22
- data/lib/liquid/strainer.rb +3 -3
- data/lib/liquid/tag.rb +1 -1
- data/lib/liquid/tags/assign.rb +14 -12
- data/lib/liquid/tags/break.rb +2 -2
- data/lib/liquid/tags/capture.rb +1 -0
- data/lib/liquid/tags/case.rb +28 -28
- data/lib/liquid/tags/continue.rb +1 -1
- data/lib/liquid/tags/cycle.rb +21 -21
- data/lib/liquid/tags/decrement.rb +7 -7
- data/lib/liquid/tags/for.rb +26 -26
- data/lib/liquid/tags/if.rb +3 -3
- data/lib/liquid/tags/ifchanged.rb +9 -9
- data/lib/liquid/tags/include.rb +42 -14
- data/lib/liquid/tags/increment.rb +7 -7
- data/lib/liquid/tags/raw.rb +5 -4
- data/lib/liquid/tags/unless.rb +8 -8
- data/lib/liquid/template.rb +11 -5
- data/lib/liquid/utils.rb +0 -1
- data/lib/liquid/variable.rb +2 -2
- data/lib/liquid/version.rb +4 -0
- data/test/liquid/assign_test.rb +1 -1
- data/test/liquid/condition_test.rb +1 -1
- data/test/liquid/hash_ordering_test.rb +25 -0
- data/test/liquid/output_test.rb +2 -2
- data/test/liquid/standard_filter_test.rb +18 -0
- data/test/liquid/tags/for_tag_test.rb +47 -34
- data/test/liquid/tags/html_tag_test.rb +2 -2
- data/test/liquid/tags/if_else_tag_test.rb +0 -6
- data/test/liquid/tags/include_tag_test.rb +28 -1
- data/test/liquid/tags/raw_tag_test.rb +11 -2
- data/test/liquid/template_test.rb +72 -0
- data/test/liquid/variable_test.rb +6 -0
- metadata +8 -5
data/lib/liquid/strainer.rb
CHANGED
@@ -8,7 +8,7 @@ module Liquid
|
|
8
8
|
# The Strainer only allows method calls defined in filters given to it via Strainer.global_filter,
|
9
9
|
# Context#add_filters or Template.register_filter
|
10
10
|
class Strainer #:nodoc:
|
11
|
-
@@filters =
|
11
|
+
@@filters = []
|
12
12
|
@@known_filters = Set.new
|
13
13
|
@@known_methods = Set.new
|
14
14
|
|
@@ -19,7 +19,7 @@ module Liquid
|
|
19
19
|
def self.global_filter(filter)
|
20
20
|
raise ArgumentError, "Passed filter is not a module" unless filter.is_a?(Module)
|
21
21
|
add_known_filter(filter)
|
22
|
-
@@filters
|
22
|
+
@@filters << filter unless @@filters.include?(filter)
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.add_known_filter(filter)
|
@@ -34,7 +34,7 @@ module Liquid
|
|
34
34
|
|
35
35
|
def self.create(context)
|
36
36
|
strainer = Strainer.new(context)
|
37
|
-
@@filters.each { |
|
37
|
+
@@filters.each { |m| strainer.extend(m) }
|
38
38
|
strainer
|
39
39
|
end
|
40
40
|
|
data/lib/liquid/tag.rb
CHANGED
data/lib/liquid/tags/assign.rb
CHANGED
@@ -10,24 +10,26 @@ module Liquid
|
|
10
10
|
#
|
11
11
|
class Assign < Tag
|
12
12
|
Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/o
|
13
|
-
|
14
|
-
def initialize(tag_name, markup, tokens)
|
13
|
+
|
14
|
+
def initialize(tag_name, markup, tokens)
|
15
15
|
if markup =~ Syntax
|
16
16
|
@to = $1
|
17
17
|
@from = Variable.new($2)
|
18
18
|
else
|
19
19
|
raise SyntaxError.new("Syntax Error in 'assign' - Valid syntax: assign [var] = [source]")
|
20
20
|
end
|
21
|
-
|
22
|
-
super
|
21
|
+
|
22
|
+
super
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def render(context)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
val = @from.render(context)
|
27
|
+
context.scopes.last[@to] = val
|
28
|
+
context.resource_limits[:assign_score_current] += (val.respond_to?(:length) ? val.length : 1)
|
29
|
+
''
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
Template.register_tag('assign', Assign)
|
33
35
|
end
|
data/lib/liquid/tags/break.rb
CHANGED
data/lib/liquid/tags/capture.rb
CHANGED
data/lib/liquid/tags/case.rb
CHANGED
@@ -3,15 +3,15 @@ module Liquid
|
|
3
3
|
Syntax = /(#{QuotedFragment})/o
|
4
4
|
WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/o
|
5
5
|
|
6
|
-
def initialize(tag_name, markup, tokens)
|
6
|
+
def initialize(tag_name, markup, tokens)
|
7
7
|
@blocks = []
|
8
|
-
|
8
|
+
|
9
9
|
if markup =~ Syntax
|
10
10
|
@left = $1
|
11
11
|
else
|
12
12
|
raise SyntaxError.new("Syntax Error in tag 'case' - Valid syntax: case [condition]")
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
@@ -27,53 +27,53 @@ module Liquid
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def render(context)
|
31
|
-
context.stack do
|
30
|
+
def render(context)
|
31
|
+
context.stack do
|
32
32
|
execute_else_block = true
|
33
|
-
|
33
|
+
|
34
34
|
output = ''
|
35
35
|
@blocks.each do |block|
|
36
|
-
if block.else?
|
36
|
+
if block.else?
|
37
37
|
return render_all(block.attachment, context) if execute_else_block
|
38
38
|
elsif block.evaluate(context)
|
39
|
-
execute_else_block = false
|
39
|
+
execute_else_block = false
|
40
40
|
output << render_all(block.attachment, context)
|
41
|
-
end
|
41
|
+
end
|
42
42
|
end
|
43
43
|
output
|
44
|
-
end
|
44
|
+
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
private
|
48
|
-
|
49
|
-
def record_when_condition(markup)
|
48
|
+
|
49
|
+
def record_when_condition(markup)
|
50
50
|
while markup
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
# Create a new nodelist and assign it to the new block
|
52
|
+
if not markup =~ WhenSyntax
|
53
|
+
raise SyntaxError.new("Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %} ")
|
54
|
+
end
|
55
55
|
|
56
|
-
|
56
|
+
markup = $2
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
block = Condition.new(@left, '==', $1)
|
59
|
+
block.attach(@nodelist)
|
60
|
+
@blocks.push(block)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
-
def record_else_condition(markup)
|
64
|
+
def record_else_condition(markup)
|
65
65
|
|
66
66
|
if not markup.strip.empty?
|
67
67
|
raise SyntaxError.new("Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) ")
|
68
68
|
end
|
69
|
-
|
70
|
-
block = ElseCondition.new
|
69
|
+
|
70
|
+
block = ElseCondition.new
|
71
71
|
block.attach(@nodelist)
|
72
72
|
@blocks << block
|
73
73
|
end
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
78
|
Template.register_tag('case', Case)
|
79
79
|
end
|
data/lib/liquid/tags/continue.rb
CHANGED
data/lib/liquid/tags/cycle.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
2
|
+
|
3
3
|
# Cycle is usually used within a loop to alternate between values, like colors or DOM classes.
|
4
4
|
#
|
5
5
|
# {% for item in items %}
|
@@ -15,45 +15,45 @@ module Liquid
|
|
15
15
|
class Cycle < Tag
|
16
16
|
SimpleSyntax = /^#{QuotedFragment}+/o
|
17
17
|
NamedSyntax = /^(#{QuotedFragment})\s*\:\s*(.*)/o
|
18
|
-
|
19
|
-
def initialize(tag_name, markup, tokens)
|
18
|
+
|
19
|
+
def initialize(tag_name, markup, tokens)
|
20
20
|
case markup
|
21
21
|
when NamedSyntax
|
22
|
-
|
23
|
-
|
22
|
+
@variables = variables_from_string($2)
|
23
|
+
@name = $1
|
24
24
|
when SimpleSyntax
|
25
25
|
@variables = variables_from_string(markup)
|
26
|
-
|
26
|
+
@name = "'#{@variables.to_s}'"
|
27
27
|
else
|
28
28
|
raise SyntaxError.new("Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]")
|
29
29
|
end
|
30
|
-
super
|
31
|
-
end
|
32
|
-
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
33
|
def render(context)
|
34
34
|
context.registers[:cycle] ||= Hash.new(0)
|
35
|
-
|
35
|
+
|
36
36
|
context.stack do
|
37
|
-
key = context[@name]
|
37
|
+
key = context[@name]
|
38
38
|
iteration = context.registers[:cycle][key]
|
39
39
|
result = context[@variables[iteration]]
|
40
|
-
iteration += 1
|
41
|
-
iteration = 0 if iteration >= @variables.size
|
40
|
+
iteration += 1
|
41
|
+
iteration = 0 if iteration >= @variables.size
|
42
42
|
context.registers[:cycle][key] = iteration
|
43
|
-
result
|
43
|
+
result
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
private
|
48
|
-
|
48
|
+
|
49
49
|
def variables_from_string(markup)
|
50
50
|
markup.split(',').collect do |var|
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
var =~ /\s*(#{QuotedFragment})\s*/o
|
52
|
+
$1 ? $1 : nil
|
53
|
+
end.compact
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
Template.register_tag('cycle', Cycle)
|
59
59
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
2
|
+
|
3
3
|
# decrement is used in a place where one needs to insert a counter
|
4
4
|
# into a template, and needs the counter to survive across
|
5
5
|
# multiple instantiations of the template.
|
@@ -19,21 +19,21 @@ module Liquid
|
|
19
19
|
# Hello: -3
|
20
20
|
#
|
21
21
|
class Decrement < Tag
|
22
|
-
def initialize(tag_name, markup, tokens)
|
22
|
+
def initialize(tag_name, markup, tokens)
|
23
23
|
@variable = markup.strip
|
24
24
|
|
25
|
-
super
|
26
|
-
end
|
27
|
-
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
28
|
def render(context)
|
29
29
|
value = context.environments.first[@variable] ||= 0
|
30
30
|
value = value - 1
|
31
31
|
context.environments.first[@variable] = value
|
32
32
|
value.to_s
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
private
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
Template.register_tag('decrement', Decrement)
|
39
39
|
end
|
data/lib/liquid/tags/for.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Liquid
|
2
2
|
|
3
|
-
# "For" iterates over an array or collection.
|
3
|
+
# "For" iterates over an array or collection.
|
4
4
|
# Several useful variables are available to you within the loop.
|
5
5
|
#
|
6
6
|
# == Basic usage:
|
@@ -22,7 +22,7 @@ module Liquid
|
|
22
22
|
#
|
23
23
|
# {% for item in collection limit:5 offset:10 %}
|
24
24
|
# {{ item.name }}
|
25
|
-
# {% end %}
|
25
|
+
# {% end %}
|
26
26
|
#
|
27
27
|
# To reverse the for loop simply use {% for item in collection reversed %}
|
28
28
|
#
|
@@ -31,7 +31,7 @@ module Liquid
|
|
31
31
|
# forloop.name:: 'item-collection'
|
32
32
|
# forloop.length:: Length of the loop
|
33
33
|
# forloop.index:: The current item's position in the collection;
|
34
|
-
# forloop.index starts at 1.
|
34
|
+
# forloop.index starts at 1.
|
35
35
|
# This is helpful for non-programmers who start believe
|
36
36
|
# the first item in an array is 1, not 0.
|
37
37
|
# forloop.index0:: The current item's position in the collection
|
@@ -43,19 +43,19 @@ module Liquid
|
|
43
43
|
# forloop.first:: Returns true if the item is the first item.
|
44
44
|
# forloop.last:: Returns true if the item is the last item.
|
45
45
|
#
|
46
|
-
class For < Block
|
47
|
-
Syntax =
|
48
|
-
|
46
|
+
class For < Block
|
47
|
+
Syntax = /\A(\w+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o
|
48
|
+
|
49
49
|
def initialize(tag_name, markup, tokens)
|
50
50
|
if markup =~ Syntax
|
51
51
|
@variable_name = $1
|
52
52
|
@collection_name = $2
|
53
|
-
@name = "#{$1}-#{$2}"
|
54
|
-
@reversed = $3
|
53
|
+
@name = "#{$1}-#{$2}"
|
54
|
+
@reversed = $3
|
55
55
|
@attributes = {}
|
56
56
|
markup.scan(TagAttributes) do |key, value|
|
57
57
|
@attributes[key] = value
|
58
|
-
end
|
58
|
+
end
|
59
59
|
else
|
60
60
|
raise SyntaxError.new("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]")
|
61
61
|
end
|
@@ -68,51 +68,51 @@ module Liquid
|
|
68
68
|
return super unless tag == 'else'
|
69
69
|
@nodelist = @else_block = []
|
70
70
|
end
|
71
|
-
|
72
|
-
def render(context)
|
71
|
+
|
72
|
+
def render(context)
|
73
73
|
context.registers[:for] ||= Hash.new(0)
|
74
|
-
|
74
|
+
|
75
75
|
collection = context[@collection_name]
|
76
76
|
collection = collection.to_a if collection.is_a?(Range)
|
77
|
-
|
77
|
+
|
78
78
|
# Maintains Ruby 1.8.7 String#each behaviour on 1.9
|
79
79
|
return render_else(context) unless iterable?(collection)
|
80
|
-
|
80
|
+
|
81
81
|
from = if @attributes['offset'] == 'continue'
|
82
82
|
context.registers[:for][@name].to_i
|
83
83
|
else
|
84
84
|
context[@attributes['offset']].to_i
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
limit = context[@attributes['limit']]
|
88
|
-
to = limit ? limit.to_i + from : nil
|
88
|
+
to = limit ? limit.to_i + from : nil
|
89
89
|
|
90
90
|
|
91
91
|
segment = Utils.slice_collection_using_each(collection, from, to)
|
92
92
|
|
93
93
|
return render_else(context) if segment.empty?
|
94
|
-
|
94
|
+
|
95
95
|
segment.reverse! if @reversed
|
96
96
|
|
97
97
|
result = ''
|
98
|
-
|
99
|
-
length = segment.length
|
100
|
-
|
98
|
+
|
99
|
+
length = segment.length
|
100
|
+
|
101
101
|
# Store our progress through the collection for the continue flag
|
102
102
|
context.registers[:for][@name] = from + segment.length
|
103
|
-
|
103
|
+
|
104
104
|
context.stack do
|
105
105
|
segment.each_with_index do |item, index|
|
106
106
|
context[@variable_name] = item
|
107
107
|
context['forloop'] = {
|
108
108
|
'name' => @name,
|
109
109
|
'length' => length,
|
110
|
-
'index' => index + 1,
|
111
|
-
'index0' => index,
|
110
|
+
'index' => index + 1,
|
111
|
+
'index0' => index,
|
112
112
|
'rindex' => length - index,
|
113
113
|
'rindex0' => length - index - 1,
|
114
114
|
'first' => (index == 0),
|
115
|
-
|
115
|
+
'last' => (index == length - 1) }
|
116
116
|
|
117
117
|
result << render_all(@for_block, context)
|
118
118
|
|
@@ -124,8 +124,8 @@ module Liquid
|
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
127
|
-
result
|
128
|
-
end
|
127
|
+
result
|
128
|
+
end
|
129
129
|
|
130
130
|
private
|
131
131
|
|
data/lib/liquid/tags/if.rb
CHANGED
@@ -15,7 +15,6 @@ module Liquid
|
|
15
15
|
SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
16
16
|
Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/o
|
17
17
|
ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o
|
18
|
-
BOOLEAN_OPERATORS = %w(and or)
|
19
18
|
|
20
19
|
def initialize(tag_name, markup, tokens)
|
21
20
|
@blocks = []
|
@@ -62,8 +61,7 @@ module Liquid
|
|
62
61
|
raise(SyntaxError, SyntaxHelp) unless expressions.shift.to_s =~ Syntax
|
63
62
|
|
64
63
|
new_condition = Condition.new($1, $2, $3)
|
65
|
-
|
66
|
-
new_condition.send(operator, condition)
|
64
|
+
new_condition.send(operator.to_sym, condition)
|
67
65
|
condition = new_condition
|
68
66
|
end
|
69
67
|
|
@@ -73,6 +71,8 @@ module Liquid
|
|
73
71
|
@blocks.push(block)
|
74
72
|
@nodelist = block.attach(Array.new)
|
75
73
|
end
|
74
|
+
|
75
|
+
|
76
76
|
end
|
77
77
|
|
78
78
|
Template.register_tag('if', If)
|