liquid 1.9.0 → 2.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.
- data/Manifest.txt +0 -31
- data/Rakefile +1 -1
- data/lib/extras/liquid_view.rb +15 -2
- data/lib/liquid.rb +15 -15
- data/lib/liquid/block.rb +1 -2
- data/lib/liquid/context.rb +89 -99
- data/lib/liquid/drop.rb +6 -4
- data/lib/liquid/errors.rb +1 -0
- data/lib/liquid/standardfilters.rb +56 -11
- data/lib/liquid/strainer.rb +1 -1
- data/lib/liquid/tags/assign.rb +1 -1
- data/lib/liquid/tags/case.rb +2 -2
- data/lib/liquid/tags/cycle.rb +3 -4
- data/lib/liquid/tags/for.rb +53 -35
- data/lib/liquid/tags/if.rb +3 -3
- data/lib/liquid/template.rb +8 -7
- data/lib/liquid/variable.rb +10 -11
- metadata +5 -35
- data/example/server/example_servlet.rb +0 -37
- data/example/server/liquid_servlet.rb +0 -28
- data/example/server/server.rb +0 -12
- data/example/server/templates/index.liquid +0 -6
- data/example/server/templates/products.liquid +0 -45
- data/test/block_test.rb +0 -58
- data/test/condition_test.rb +0 -109
- data/test/context_test.rb +0 -418
- data/test/drop_test.rb +0 -141
- data/test/error_handling_test.rb +0 -78
- data/test/extra/breakpoint.rb +0 -547
- data/test/extra/caller.rb +0 -80
- data/test/file_system_test.rb +0 -30
- data/test/filter_test.rb +0 -98
- data/test/helper.rb +0 -20
- data/test/html_tag_test.rb +0 -31
- data/test/if_else_test.rb +0 -127
- data/test/include_tag_test.rb +0 -114
- data/test/module_ex_test.rb +0 -89
- data/test/output_test.rb +0 -121
- data/test/parsing_quirks_test.rb +0 -29
- data/test/regexp_test.rb +0 -40
- data/test/security_test.rb +0 -41
- data/test/standard_filter_test.rb +0 -126
- data/test/standard_tag_test.rb +0 -383
- data/test/statements_test.rb +0 -137
- data/test/strainer_test.rb +0 -16
- data/test/template_test.rb +0 -26
- data/test/unless_else_test.rb +0 -27
- data/test/variable_test.rb +0 -135
data/lib/liquid/drop.rb
CHANGED
@@ -28,10 +28,12 @@ module Liquid
|
|
28
28
|
end
|
29
29
|
|
30
30
|
# called by liquid to invoke a drop
|
31
|
-
def invoke_drop(method)
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
def invoke_drop(method)
|
32
|
+
if self.class.public_instance_methods.include?(method.to_s)
|
33
|
+
send(method.to_sym)
|
34
|
+
else
|
35
|
+
before_method(method)
|
36
|
+
end
|
35
37
|
end
|
36
38
|
|
37
39
|
def has_key?(name)
|
data/lib/liquid/errors.rb
CHANGED
@@ -63,9 +63,27 @@ module Liquid
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Sort elements of the array
|
66
|
-
|
67
|
-
|
66
|
+
# provide optional property with which to sort an array of hashes or drops
|
67
|
+
def sort(input, property = nil)
|
68
|
+
ary = [input].flatten
|
69
|
+
if property.nil?
|
70
|
+
ary.sort
|
71
|
+
elsif ary.first.respond_to?('[]') and !ary.first[property].nil?
|
72
|
+
ary.sort {|a,b| a[property] <=> b[property] }
|
73
|
+
elsif ary.first.respond_to?(property)
|
74
|
+
ary.sort {|a,b| a.send(property) <=> b.send(property) }
|
75
|
+
end
|
68
76
|
end
|
77
|
+
|
78
|
+
# map/collect on a given property
|
79
|
+
def map(input, property)
|
80
|
+
ary = [input].flatten
|
81
|
+
if ary.first.respond_to?('[]') and !ary.first[property].nil?
|
82
|
+
ary.map {|e| e[property] }
|
83
|
+
elsif ary.first.respond_to?(property)
|
84
|
+
ary.map {|e| e.send(property) }
|
85
|
+
end
|
86
|
+
end
|
69
87
|
|
70
88
|
# Replace occurrences of a string with another
|
71
89
|
def replace(input, string, replacement = '')
|
@@ -85,7 +103,17 @@ module Liquid
|
|
85
103
|
# remove the first occurrences of a substring
|
86
104
|
def remove_first(input, string)
|
87
105
|
input.to_s.sub(string, '')
|
88
|
-
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# add one string to another
|
109
|
+
def append(input, string)
|
110
|
+
input.to_s + string.to_s
|
111
|
+
end
|
112
|
+
|
113
|
+
# prepend a string to another
|
114
|
+
def prepend(input, string)
|
115
|
+
string.to_s + input.to_s
|
116
|
+
end
|
89
117
|
|
90
118
|
# Add <br /> tags in front of all newlines in input string
|
91
119
|
def newline_to_br(input)
|
@@ -126,16 +154,13 @@ module Liquid
|
|
126
154
|
return input.to_s
|
127
155
|
end
|
128
156
|
|
129
|
-
date =
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
input
|
157
|
+
date = input.is_a?(String) ? Time.parse(input) : input
|
158
|
+
|
159
|
+
if date.respond_to?(:strftime)
|
160
|
+
date.strftime(format.to_s)
|
134
161
|
else
|
135
|
-
|
162
|
+
input
|
136
163
|
end
|
137
|
-
|
138
|
-
date.strftime(format.to_s)
|
139
164
|
rescue => e
|
140
165
|
input
|
141
166
|
end
|
@@ -158,6 +183,26 @@ module Liquid
|
|
158
183
|
array.last if array.respond_to?(:last)
|
159
184
|
end
|
160
185
|
|
186
|
+
# addition
|
187
|
+
def plus(input, operand)
|
188
|
+
input + operand if input.respond_to?('+')
|
189
|
+
end
|
190
|
+
|
191
|
+
# subtraction
|
192
|
+
def minus(input, operand)
|
193
|
+
input - operand if input.respond_to?('-')
|
194
|
+
end
|
195
|
+
|
196
|
+
# multiplication
|
197
|
+
def times(input, operand)
|
198
|
+
input * operand if input.respond_to?('*')
|
199
|
+
end
|
200
|
+
|
201
|
+
# division
|
202
|
+
def divided_by(input, operand)
|
203
|
+
input / operand if input.respond_to?('/')
|
204
|
+
end
|
205
|
+
|
161
206
|
end
|
162
207
|
|
163
208
|
Template.register_filter(StandardFilters)
|
data/lib/liquid/strainer.rb
CHANGED
data/lib/liquid/tags/assign.rb
CHANGED
data/lib/liquid/tags/case.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Liquid
|
2
2
|
class Case < Block
|
3
|
-
Syntax = /(#{
|
4
|
-
WhenSyntax = /(#{
|
3
|
+
Syntax = /(#{Expression})/
|
4
|
+
WhenSyntax = /(#{Expression})(?:(?:\s+or\s+|\s*\,\s*)(#{Expression}.*))?/
|
5
5
|
|
6
6
|
def initialize(tag_name, markup, tokens)
|
7
7
|
@blocks = []
|
data/lib/liquid/tags/cycle.rb
CHANGED
@@ -13,8 +13,8 @@ module Liquid
|
|
13
13
|
# <div class="green"> Item five</div>
|
14
14
|
#
|
15
15
|
class Cycle < Tag
|
16
|
-
SimpleSyntax =
|
17
|
-
NamedSyntax
|
16
|
+
SimpleSyntax = /^#{Expression}/
|
17
|
+
NamedSyntax = /^(#{Expression})\s*\:\s*(.*)/
|
18
18
|
|
19
19
|
def initialize(tag_name, markup, tokens)
|
20
20
|
case markup
|
@@ -27,7 +27,6 @@ module Liquid
|
|
27
27
|
else
|
28
28
|
raise SyntaxError.new("Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]")
|
29
29
|
end
|
30
|
-
|
31
30
|
super
|
32
31
|
end
|
33
32
|
|
@@ -49,7 +48,7 @@ module Liquid
|
|
49
48
|
|
50
49
|
def variables_from_string(markup)
|
51
50
|
markup.split(',').collect do |var|
|
52
|
-
var =~ /\s*(#{
|
51
|
+
var =~ /\s*(#{Expression})\s*/
|
53
52
|
$1 ? $1 : nil
|
54
53
|
end.compact
|
55
54
|
end
|
data/lib/liquid/tags/for.rb
CHANGED
@@ -20,7 +20,9 @@ module Liquid
|
|
20
20
|
#
|
21
21
|
# {% for item in collection limit:5 offset:10 %}
|
22
22
|
# {{ item.name }}
|
23
|
-
# {% end %}
|
23
|
+
# {% end %}
|
24
|
+
#
|
25
|
+
# To reverse the for loop simply use {% for item in collection reversed %}
|
24
26
|
#
|
25
27
|
# == Available variables:
|
26
28
|
#
|
@@ -40,13 +42,14 @@ module Liquid
|
|
40
42
|
# forloop.last:: Returns true if the item is the last item.
|
41
43
|
#
|
42
44
|
class For < Block
|
43
|
-
Syntax = /(\w+)\s+in\s+(#{
|
45
|
+
Syntax = /(\w+)\s+in\s+(#{Expression}+)\s*(reversed)?/
|
44
46
|
|
45
47
|
def initialize(tag_name, markup, tokens)
|
46
48
|
if markup =~ Syntax
|
47
49
|
@variable_name = $1
|
48
50
|
@collection_name = $2
|
49
|
-
@name = "#{$1}-#{$2}"
|
51
|
+
@name = "#{$1}-#{$2}"
|
52
|
+
@reversed = $3
|
50
53
|
@attributes = {}
|
51
54
|
markup.scan(TagAttributes) do |key, value|
|
52
55
|
@attributes[key] = value
|
@@ -64,35 +67,33 @@ module Liquid
|
|
64
67
|
collection = context[@collection_name]
|
65
68
|
collection = collection.to_a if collection.is_a?(Range)
|
66
69
|
|
67
|
-
return ''
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
offset
|
73
|
-
if @attributes['offset'] == 'continue'
|
74
|
-
offset = context.registers[:for][@name]
|
75
|
-
else
|
76
|
-
offset = context[@attributes['offset']] || 0
|
77
|
-
end
|
78
|
-
limit = context[@attributes['limit']]
|
79
|
-
|
80
|
-
range_end = limit ? offset + limit : collection.length
|
81
|
-
range = (offset..range_end-1)
|
82
|
-
|
83
|
-
# Save the range end in the registers so that future calls to
|
84
|
-
# offset:continue have something to pick up
|
85
|
-
context.registers[:for][@name] = range_end
|
70
|
+
return '' unless collection.respond_to?(:each)
|
71
|
+
|
72
|
+
from = if @attributes['offset'] == 'continue'
|
73
|
+
context.registers[:for][@name].to_i
|
74
|
+
else
|
75
|
+
context[@attributes['offset']].to_i
|
86
76
|
end
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
77
|
+
|
78
|
+
limit = context[@attributes['limit']]
|
79
|
+
to = limit ? limit.to_i + from : nil
|
80
|
+
|
81
|
+
|
82
|
+
segment = slice_collection_using_each(collection, from, to)
|
83
|
+
|
84
|
+
return '' if segment.empty?
|
85
|
+
|
86
|
+
segment.reverse! if @reversed
|
91
87
|
|
88
|
+
result = []
|
89
|
+
|
90
|
+
length = segment.length
|
91
|
+
|
92
|
+
# Store our progress through the collection for the continue flag
|
93
|
+
context.registers[:for][@name] = from + segment.length
|
94
|
+
|
92
95
|
context.stack do
|
93
|
-
|
94
|
-
|
95
|
-
segment.each_with_index do |item, index|
|
96
|
+
segment.each_with_index do |item, index|
|
96
97
|
context[@variable_name] = item
|
97
98
|
context['forloop'] = {
|
98
99
|
'name' => @name,
|
@@ -103,15 +104,32 @@ module Liquid
|
|
103
104
|
'rindex0' => length - index -1,
|
104
105
|
'first' => (index == 0),
|
105
106
|
'last' => (index == length - 1) }
|
106
|
-
|
107
|
+
|
107
108
|
result << render_all(@nodelist, context)
|
108
109
|
end
|
109
110
|
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
111
|
+
result
|
112
|
+
end
|
113
|
+
|
114
|
+
def slice_collection_using_each(collection, from, to)
|
115
|
+
segments = []
|
116
|
+
index = 0
|
117
|
+
yielded = 0
|
118
|
+
collection.each do |item|
|
119
|
+
|
120
|
+
if to && to <= index
|
121
|
+
break
|
122
|
+
end
|
123
|
+
|
124
|
+
if from <= index
|
125
|
+
segments << item
|
126
|
+
end
|
127
|
+
|
128
|
+
index += 1
|
129
|
+
end
|
130
|
+
|
131
|
+
segments
|
132
|
+
end
|
115
133
|
end
|
116
134
|
|
117
135
|
Template.register_tag('for', For)
|
data/lib/liquid/tags/if.rb
CHANGED
@@ -13,7 +13,7 @@ module Liquid
|
|
13
13
|
#
|
14
14
|
class If < Block
|
15
15
|
SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
16
|
-
Syntax = /(#{
|
16
|
+
Syntax = /(#{Expression})\s*([=!<>a-z_]+)?\s*(#{Expression})?/
|
17
17
|
|
18
18
|
def initialize(tag_name, markup, tokens)
|
19
19
|
|
@@ -51,14 +51,14 @@ module Liquid
|
|
51
51
|
else
|
52
52
|
|
53
53
|
expressions = markup.split(/\b(and|or)\b/).reverse
|
54
|
-
raise SyntaxHelp unless expressions.shift =~ Syntax
|
54
|
+
raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax
|
55
55
|
|
56
56
|
condition = Condition.new($1, $2, $3)
|
57
57
|
|
58
58
|
while not expressions.empty?
|
59
59
|
operator = expressions.shift
|
60
60
|
|
61
|
-
raise SyntaxHelp unless expressions.shift.to_s =~ Syntax
|
61
|
+
raise(SyntaxError, SyntaxHelp) unless expressions.shift.to_s =~ Syntax
|
62
62
|
|
63
63
|
new_condition = Condition.new($1, $2, $3)
|
64
64
|
new_condition.send(operator.to_sym, condition)
|
data/lib/liquid/template.rb
CHANGED
@@ -83,7 +83,7 @@ module Liquid
|
|
83
83
|
# filters and tags and might be useful to integrate liquid more with its host application
|
84
84
|
#
|
85
85
|
def render(*args)
|
86
|
-
return '' if @root.nil?
|
86
|
+
return '' if @root.nil?
|
87
87
|
|
88
88
|
context = case args.first
|
89
89
|
when Liquid::Context
|
@@ -107,17 +107,17 @@ module Liquid
|
|
107
107
|
|
108
108
|
if options[:filters]
|
109
109
|
context.add_filters(options[:filters])
|
110
|
-
end
|
110
|
+
end
|
111
|
+
|
111
112
|
when Module
|
112
113
|
context.add_filters(args.pop)
|
113
114
|
when Array
|
114
115
|
context.add_filters(args.pop)
|
115
116
|
end
|
116
|
-
|
117
|
-
|
118
|
-
# render the nodelist.
|
119
|
-
# for performance reasons we get a array back here. to_s will make a string out of it
|
117
|
+
|
120
118
|
begin
|
119
|
+
# render the nodelist.
|
120
|
+
# for performance reasons we get a array back here. join will make a string out of it
|
121
121
|
@root.render(context).join
|
122
122
|
ensure
|
123
123
|
@errors = context.errors
|
@@ -131,7 +131,8 @@ module Liquid
|
|
131
131
|
private
|
132
132
|
|
133
133
|
# Uses the <tt>Liquid::TemplateParser</tt> regexp to tokenize the passed source
|
134
|
-
def tokenize(source)
|
134
|
+
def tokenize(source)
|
135
|
+
source = source.source if source.respond_to?(:source)
|
135
136
|
return [] if source.to_s.empty?
|
136
137
|
tokens = source.split(TemplateParser)
|
137
138
|
|
data/lib/liquid/variable.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
2
|
+
|
3
3
|
# Holds variables. Variables are only loaded "just in time"
|
4
4
|
# and are not evaluated as part of the render stage
|
5
5
|
#
|
@@ -10,30 +10,29 @@ module Liquid
|
|
10
10
|
#
|
11
11
|
# {{ user | link }}
|
12
12
|
#
|
13
|
-
class Variable
|
13
|
+
class Variable
|
14
14
|
attr_accessor :filters, :name
|
15
|
-
|
15
|
+
|
16
16
|
def initialize(markup)
|
17
|
-
@markup = markup
|
17
|
+
@markup = markup
|
18
18
|
@name = nil
|
19
19
|
@filters = []
|
20
20
|
if match = markup.match(/\s*(#{QuotedFragment})/)
|
21
21
|
@name = match[1]
|
22
|
-
if markup.match(/#{
|
23
|
-
filters = Regexp.last_match(1).split(/#{
|
24
|
-
|
22
|
+
if markup.match(/#{FilterSeparator}\s*(.*)/)
|
23
|
+
filters = Regexp.last_match(1).split(/#{FilterSeparator}/)
|
25
24
|
filters.each do |f|
|
26
25
|
if matches = f.match(/\s*(\w+)/)
|
27
26
|
filtername = matches[1]
|
28
|
-
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*(#{QuotedFragment})/).flatten
|
27
|
+
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*(#{QuotedFragment})/).flatten
|
29
28
|
@filters << [filtername.to_sym, filterargs]
|
30
29
|
end
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
34
|
-
end
|
33
|
+
end
|
35
34
|
|
36
|
-
def render(context)
|
35
|
+
def render(context)
|
37
36
|
return '' if @name.nil?
|
38
37
|
output = context[@name]
|
39
38
|
@filters.inject(output) do |output, filter|
|
@@ -45,7 +44,7 @@ module Liquid
|
|
45
44
|
rescue FilterNotFound
|
46
45
|
raise FilterNotFound, "Error - filter '#{filter[0]}' in '#{@markup.strip}' could not be found."
|
47
46
|
end
|
48
|
-
end
|
47
|
+
end
|
49
48
|
output
|
50
49
|
end
|
51
50
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: liquid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
@@ -9,17 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-03-10 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hoe
|
17
|
+
type: :development
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - ">="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
23
|
+
version: 1.8.2
|
23
24
|
version:
|
24
25
|
description: A secure non evaling end user template engine with aesthetic markup.
|
25
26
|
email: tobi@leetsoft.com
|
@@ -38,11 +39,6 @@ files:
|
|
38
39
|
- Manifest.txt
|
39
40
|
- README.txt
|
40
41
|
- Rakefile
|
41
|
-
- example/server/example_servlet.rb
|
42
|
-
- example/server/liquid_servlet.rb
|
43
|
-
- example/server/server.rb
|
44
|
-
- example/server/templates/index.liquid
|
45
|
-
- example/server/templates/products.liquid
|
46
42
|
- init.rb
|
47
43
|
- lib/extras/liquid_view.rb
|
48
44
|
- lib/liquid.rb
|
@@ -71,32 +67,6 @@ files:
|
|
71
67
|
- lib/liquid/tags/unless.rb
|
72
68
|
- lib/liquid/template.rb
|
73
69
|
- lib/liquid/variable.rb
|
74
|
-
- test/block_test.rb
|
75
|
-
- test/condition_test.rb
|
76
|
-
- test/context_test.rb
|
77
|
-
- test/drop_test.rb
|
78
|
-
- test/error_handling_test.rb
|
79
|
-
- test/extra/breakpoint.rb
|
80
|
-
- test/extra/caller.rb
|
81
|
-
- test/file_system_test.rb
|
82
|
-
- test/filter_test.rb
|
83
|
-
- test/helper.rb
|
84
|
-
- test/html_tag_test.rb
|
85
|
-
- test/if_else_test.rb
|
86
|
-
- test/include_tag_test.rb
|
87
|
-
- test/module_ex_test.rb
|
88
|
-
- test/output_test.rb
|
89
|
-
- test/parsing_quirks_test.rb
|
90
|
-
- test/regexp_test.rb
|
91
|
-
- test/security_test.rb
|
92
|
-
- test/standard_filter_test.rb
|
93
|
-
- test/standard_tag_test.rb
|
94
|
-
- test/statements_test.rb
|
95
|
-
- test/strainer_test.rb
|
96
|
-
- test/template_test.rb
|
97
|
-
- test/test_helper.rb
|
98
|
-
- test/unless_else_test.rb
|
99
|
-
- test/variable_test.rb
|
100
70
|
has_rdoc: true
|
101
71
|
homepage: http://www.liquidmarkup.org
|
102
72
|
post_install_message:
|
@@ -120,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
90
|
requirements: []
|
121
91
|
|
122
92
|
rubyforge_project: liquid
|
123
|
-
rubygems_version: 1.1
|
93
|
+
rubygems_version: 1.3.1
|
124
94
|
signing_key:
|
125
95
|
specification_version: 2
|
126
96
|
summary: A secure non evaling end user template engine with aesthetic markup.
|