forked from tyler-sommer/stick
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilter.go
More file actions
263 lines (231 loc) · 6.52 KB
/
filter.go
File metadata and controls
263 lines (231 loc) · 6.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
package stick
import (
"math"
"strings"
"unicode/utf8"
)
// builtInFilters returns a map containing all built-in Twig filters,
// with the exception of "escape", which is provided by the AutoEscapeExtension.
func builtInFilters() map[string]Filter {
return map[string]Filter{
"abs": filterAbs,
"default": filterDefault,
"batch": filterBatch,
"capitalize": filterCapitalize,
"convert_encoding": filterConvertEncoding,
"date": filterDate,
"date_modify": filterDateModify,
"first": filterFirst,
"format": filterFormat,
"join": filterJoin,
"json_encode": filterJSONEncode,
"keys": filterKeys,
"last": filterLast,
"length": filterLength,
"lower": filterLower,
"merge": filterMerge,
"nl2br": filterNL2BR,
"number_format": filterNumberFormat,
"raw": filterRaw,
"replace": filterReplace,
"reverse": filterReverse,
"round": filterRound,
"slice": filterSlice,
"sort": filterSort,
"split": filterSplit,
"striptags": filterStripTags,
"title": filterTitle,
"trim": filterTrim,
"upper": filterUpper,
"url_encode": filterURLEncode,
}
}
// filterAbs takes no arguments and returns the absolute value of val.
// Value val will be coerced into a number.
func filterAbs(ctx Context, val Value, args ...Value) Value {
n := CoerceNumber(val)
if 0 == n {
return n
}
return math.Abs(n)
}
// filterBatch takes 2 arguments and returns a batched version of val.
// Value val must be a map, slice, or array. The filter has two optional arguments: number
// of items per batch (defaults to 1), and the default fill value. If the
// fill value is not specified, the last group of batched values may be smaller than
// the number specified as items per batch.
func filterBatch(ctx Context, val Value, args ...Value) Value {
perSlice := 1
var blankValue Value
if l := len(args); l >= 1 {
perSlice = int(CoerceNumber(args[0]))
if l >= 2 {
blankValue = args[1]
}
}
if !IsIterable(val) {
// TODO: This would trigger an E_WARNING in PHP.
return nil
}
if perSlice <= 1 {
// TODO: This would trigger an E_WARNING in PHP.
return nil
}
l, _ := Len(val)
numSlices := int(math.Ceil(float64(l) / float64(perSlice)))
out := make([][]Value, numSlices)
curr := []Value{}
i := 0
j := 0
_, err := Iterate(val, func(k, v Value, l Loop) (bool, error) {
// Use a variable length slice and append(). This maintains
// correct compatibility with Twig when the fill value is nil.
curr = append(curr, v)
j++
if j == perSlice {
out[i] = curr
curr = []Value{}
i++
j = 0
}
return false, nil
})
if err != nil {
// TODO: Report error
return nil
}
if i != numSlices {
for ; blankValue != nil && j < perSlice; j++ {
curr = append(curr, blankValue)
}
out[i] = curr
}
return out
}
// filterCapitalize takes no arguments and returns val with the first
// character capitalized.
func filterCapitalize(ctx Context, val Value, args ...Value) Value {
s := CoerceString(val)
return strings.ToUpper(s[:1]) + s[1:]
}
func filterConvertEncoding(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterDate(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterDateModify(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
// filterDefault takes one argument, the default value. If val is empty,
// the default value will be returned.
func filterDefault(ctx Context, val Value, args ...Value) Value {
var d Value
if len(args) > 0 {
d = args[0]
}
if CoerceString(val) == "" {
return d
}
return val
}
func filterFirst(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterFormat(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterJoin(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterJSONEncode(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterKeys(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterLast(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
// filterLength returns the length of val.
func filterLength(ctx Context, val Value, args ...Value) Value {
if v, ok := val.(string); ok {
return utf8.RuneCountInString(v)
}
l, _ := Len(val)
// TODO: Report error
return l
}
// filterLower returns val transformed to lower-case.
func filterLower(ctx Context, val Value, args ...Value) Value {
return strings.ToLower(CoerceString(val))
}
func filterMerge(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterNL2BR(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterNumberFormat(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterRaw(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterReplace(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterReverse(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterRound(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterSlice(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterSort(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterSplit(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
func filterStripTags(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}
// filterTitle returns val with the first character of each word capitalized.
func filterTitle(ctx Context, val Value, args ...Value) Value {
return strings.Title(CoerceString(val))
}
// filterTrim returns val with whitespace trimmed on both left and ride sides.
func filterTrim(ctx Context, val Value, args ...Value) Value {
return strings.TrimSpace(CoerceString(val))
}
// filterUpper returns val in upper-case.
func filterUpper(ctx Context, val Value, args ...Value) Value {
return strings.ToUpper(CoerceString(val))
}
func filterURLEncode(ctx Context, val Value, args ...Value) Value {
// TODO: Implement Me
return val
}