liquid 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|