line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Template::Liquid::Tag::For; |
2
|
|
|
|
|
|
|
our $VERSION = '1.0.23'; |
3
|
25
|
|
|
25
|
|
174
|
use strict; |
|
25
|
|
|
|
|
61
|
|
|
25
|
|
|
|
|
745
|
|
4
|
25
|
|
|
25
|
|
139
|
use warnings; |
|
25
|
|
|
|
|
67
|
|
|
25
|
|
|
|
|
879
|
|
5
|
|
|
|
|
|
|
require Template::Liquid::Error; |
6
|
|
|
|
|
|
|
require Template::Liquid::Utility; |
7
|
25
|
|
|
25
|
|
165
|
use base 'Template::Liquid::Tag::If'; |
|
25
|
|
|
|
|
64
|
|
|
25
|
|
|
|
|
36293
|
|
8
|
|
|
|
|
|
|
my $Help_String = 'TODO'; |
9
|
25
|
|
|
25
|
|
101
|
sub import { Template::Liquid::register_tag('for') } |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub new { |
12
|
105
|
|
|
105
|
0
|
273
|
my ($class, $args) = @_; |
13
|
|
|
|
|
|
|
raise Template::Liquid::Error {type => 'Context', |
14
|
|
|
|
|
|
|
template => $args->{template}, |
15
|
|
|
|
|
|
|
message => 'Missing template argument', |
16
|
|
|
|
|
|
|
fatal => 1 |
17
|
|
|
|
|
|
|
} |
18
|
105
|
50
|
|
|
|
256
|
if !defined $args->{'template'}; |
19
|
|
|
|
|
|
|
raise Template::Liquid::Error {type => 'Context', |
20
|
|
|
|
|
|
|
template => $args->{template}, |
21
|
|
|
|
|
|
|
message => 'Missing parent argument', |
22
|
|
|
|
|
|
|
fatal => 1 |
23
|
|
|
|
|
|
|
} |
24
|
105
|
50
|
|
|
|
230
|
if !defined $args->{'parent'}; |
25
|
|
|
|
|
|
|
raise Template::Liquid::Error { |
26
|
|
|
|
|
|
|
type => 'Syntax', |
27
|
|
|
|
|
|
|
template => $args->{template}, |
28
|
|
|
|
|
|
|
message => 'Missing argument list in ' . $args->{'markup'}, |
29
|
|
|
|
|
|
|
fatal => 1 |
30
|
|
|
|
|
|
|
} |
31
|
105
|
50
|
|
|
|
260
|
if !defined $args->{'attrs'}; |
32
|
105
|
50
|
|
|
|
1027
|
if ($args->{'attrs'} !~ qr[^([\w\.]+)\s+in\s+(.+?)(?:\s+(.*)\s*?)?$]o) { |
33
|
|
|
|
|
|
|
raise Template::Liquid::Error { |
34
|
|
|
|
|
|
|
template => $args->{template}, |
35
|
|
|
|
|
|
|
type => 'Syntax', |
36
|
0
|
|
|
|
|
0
|
message => 'Bad argument list in ' . $args->{'markup'}, |
37
|
|
|
|
|
|
|
fatal => 1 |
38
|
|
|
|
|
|
|
}; |
39
|
|
|
|
|
|
|
} |
40
|
105
|
|
100
|
|
|
717
|
my ($var, $range, $attr) = ($1, $2, $3 || ''); |
41
|
105
|
100
|
|
|
|
337
|
my $reversed = $attr =~ s[^reversed\b][]o ? 1 : 0; |
42
|
|
|
|
|
|
|
my %attr = map { |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
#my $blah = $_; |
45
|
|
|
|
|
|
|
#my ($k, $v) |
46
|
|
|
|
|
|
|
# = grep { defined $_ } |
47
|
|
|
|
|
|
|
# $_ |
48
|
|
|
|
|
|
|
# =~ m[$Template::Liquid::Utility::VariableFilterArgumentParser]g; |
49
|
|
|
|
|
|
|
#use Data::Dump; |
50
|
|
|
|
|
|
|
##ddx [$k, $v]; |
51
|
72
|
|
|
|
|
456
|
my ($k, $v) = $_ =~ m[$Template::Liquid::Utility::TagAttributes]g; |
52
|
72
|
|
|
|
|
128
|
{ $k => $v }; |
|
72
|
|
|
|
|
237
|
|
53
|
105
|
50
|
100
|
|
|
631
|
} grep { defined && length } split qr[\s+]o, $attr || ''; |
|
83
|
|
|
|
|
300
|
|
54
|
|
|
|
|
|
|
my $s = bless {attributes => \%attr, |
55
|
|
|
|
|
|
|
collection_name => $range, |
56
|
|
|
|
|
|
|
name => $var . '-' . $range, |
57
|
|
|
|
|
|
|
blocks => [], |
58
|
|
|
|
|
|
|
conditional_tag => 'else', |
59
|
|
|
|
|
|
|
reversed => $reversed, |
60
|
|
|
|
|
|
|
tag_name => $args->{'tag_name'}, |
61
|
|
|
|
|
|
|
variable_name => $var, |
62
|
|
|
|
|
|
|
end_tag => 'end' . $args->{'tag_name'}, |
63
|
|
|
|
|
|
|
template => $args->{'template'}, |
64
|
|
|
|
|
|
|
parent => $args->{'parent'}, |
65
|
105
|
|
|
|
|
1094
|
markup => $args->{'markup'} |
66
|
|
|
|
|
|
|
}, $class; |
67
|
105
|
|
|
|
|
347
|
return $s; |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub render { |
71
|
107
|
|
|
107
|
0
|
210
|
my ($s) = @_; |
72
|
107
|
|
|
|
|
190
|
my $range = $s->{'collection_name'}; |
73
|
107
|
|
|
|
|
179
|
my $attr = $s->{'attributes'}; |
74
|
107
|
|
|
|
|
159
|
my $reversed = $s->{'reversed'}; |
75
|
|
|
|
|
|
|
my $sorted |
76
|
|
|
|
|
|
|
= exists $attr->{'sorted'} |
77
|
|
|
|
|
|
|
? $s->{template}{context}->get($attr->{'sorted'}) || |
78
|
107
|
100
|
100
|
|
|
251
|
$attr->{'sorted'} || |
79
|
|
|
|
|
|
|
'key' |
80
|
|
|
|
|
|
|
: (); |
81
|
107
|
50
|
66
|
|
|
284
|
$sorted = 'key' |
|
|
|
66
|
|
|
|
|
82
|
|
|
|
|
|
|
if (defined $sorted && (($sorted ne 'key') && ($sorted ne 'value'))); |
83
|
|
|
|
|
|
|
my $offset |
84
|
|
|
|
|
|
|
= defined $attr->{'offset'} |
85
|
107
|
100
|
|
|
|
263
|
? $s->{template}{context}->get($attr->{'offset'}) |
86
|
|
|
|
|
|
|
: (); |
87
|
|
|
|
|
|
|
my $limit |
88
|
|
|
|
|
|
|
= defined $attr->{'limit'} |
89
|
107
|
100
|
|
|
|
245
|
? $s->{template}{context}->get($attr->{'limit'}) |
90
|
|
|
|
|
|
|
: (); |
91
|
107
|
|
|
|
|
293
|
my $list = $s->{template}{context}->get($range); |
92
|
107
|
|
|
|
|
203
|
my $type = 'ARRAY'; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
#warn $list; |
95
|
|
|
|
|
|
|
# |
96
|
107
|
|
|
|
|
161
|
my $_undef_list = 0; |
97
|
107
|
100
|
|
|
|
342
|
if (ref $list eq 'HASH') { |
|
|
100
|
|
|
|
|
|
98
|
16
|
|
|
|
|
55
|
$list = [map { {key => $_, value => $list->{$_}} } keys %$list]; |
|
46
|
|
|
|
|
132
|
|
99
|
|
|
|
|
|
|
@$list = sort { |
100
|
16
|
100
|
|
|
|
70
|
$a->{$sorted} =~ m[^\d+$]o && |
101
|
|
|
|
|
|
|
$b->{$sorted} =~ m[^\d+$]o |
102
|
|
|
|
|
|
|
? ($a->{$sorted} <=> $b->{$sorted}) |
103
|
31
|
100
|
66
|
|
|
158
|
: ($a->{$sorted} cmp $b->{$sorted}) |
104
|
|
|
|
|
|
|
} @$list if defined $sorted; |
105
|
16
|
|
|
|
|
31
|
$type = 'HASH'; |
106
|
|
|
|
|
|
|
} |
107
|
|
|
|
|
|
|
elsif (defined $sorted) { |
108
|
|
|
|
|
|
|
@$list = sort { |
109
|
3
|
50
|
33
|
|
|
13
|
$a =~ m[^\d+$] && $b =~ m[^\d+$] ? ($a <=> $b) : ($a cmp $b) |
|
24
|
|
|
|
|
114
|
|
110
|
|
|
|
|
|
|
} @$list; |
111
|
|
|
|
|
|
|
} |
112
|
107
|
100
|
66
|
|
|
175
|
if (!eval { \@$list }) { |
|
107
|
100
|
33
|
|
|
763
|
|
|
|
50
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# list is a string |
115
|
1
|
|
|
|
|
4
|
$list = [$list]; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
elsif (ref($list) eq 'ARRAY' && !@$list) { |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# empty array |
120
|
2
|
|
|
|
|
4
|
$_undef_list = 1; |
121
|
2
|
|
|
|
|
6
|
$list = [1]; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
elsif (!defined $list || !$list) { |
124
|
0
|
|
|
|
|
0
|
$_undef_list = 1; |
125
|
0
|
|
|
|
|
0
|
$list = [1]; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
else { # Break it down to only the items we plan on using |
128
|
104
|
100
|
|
|
|
244
|
my $min = (defined $offset ? $offset : 0); |
129
|
104
|
100
|
|
|
|
270
|
my $max |
|
|
100
|
|
|
|
|
|
130
|
|
|
|
|
|
|
= (defined $limit |
131
|
|
|
|
|
|
|
? $limit + (defined $offset ? $offset : 0) - 1 |
132
|
|
|
|
|
|
|
: $#$list); |
133
|
104
|
100
|
|
|
|
223
|
$max = $#$list if $max > $#$list; |
134
|
104
|
|
|
|
|
246
|
$list = [@{$list}[$min .. $max]] |
|
104
|
|
|
|
|
290
|
|
135
|
|
|
|
|
|
|
; # make a copy so we can use the list again |
136
|
104
|
100
|
|
|
|
259
|
@$list = reverse @$list if $reversed; |
137
|
104
|
100
|
|
|
|
233
|
$limit = defined $limit ? $limit : scalar @$list; |
138
|
104
|
100
|
|
|
|
220
|
$offset = defined $offset ? $offset : 0; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
return $s->{template}{context}->stack( |
141
|
|
|
|
|
|
|
sub { |
142
|
107
|
|
|
107
|
|
203
|
my $return = ''; |
143
|
107
|
|
|
|
|
183
|
my $steps = $#$list; |
144
|
107
|
100
|
|
|
|
248
|
$_undef_list = 1 if $steps == -1; |
145
|
107
|
|
|
|
|
216
|
my $nodes = $s->{'blocks'}[$_undef_list]{'nodelist'}; |
146
|
107
|
|
|
|
|
339
|
FOR: for my $index (0 .. $steps) { |
147
|
|
|
|
|
|
|
$s->{template}{context} |
148
|
387
|
|
|
|
|
1238
|
->set($s->{'variable_name'}, $list->[$index]); |
149
|
|
|
|
|
|
|
$s->{template}{context}->set( |
150
|
|
|
|
|
|
|
'forloop', |
151
|
|
|
|
|
|
|
{length => $steps + 1, |
152
|
|
|
|
|
|
|
limit => $limit, |
153
|
|
|
|
|
|
|
offset => $offset, |
154
|
387
|
100
|
|
|
|
3669
|
name => $s->{'name'}, |
|
|
100
|
|
|
|
|
|
155
|
|
|
|
|
|
|
first => ($index == 0 ? !!1 : !1), |
156
|
|
|
|
|
|
|
last => ($index == $steps ? !!1 : !1), |
157
|
|
|
|
|
|
|
index => $index + 1, |
158
|
|
|
|
|
|
|
index0 => $index, |
159
|
|
|
|
|
|
|
rindex => $steps - $index + 1, |
160
|
|
|
|
|
|
|
rindex0 => $steps - $index, |
161
|
|
|
|
|
|
|
type => $type, |
162
|
|
|
|
|
|
|
sorted => $sorted |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
); |
165
|
387
|
|
|
|
|
1022
|
for my $node (@$nodes) { |
166
|
1268
|
100
|
|
|
|
2746
|
my $rendering = ref $node ? $node->render() : $node; |
167
|
1268
|
100
|
|
|
|
2529
|
$return .= defined $rendering ? $rendering : ''; |
168
|
1268
|
100
|
|
|
|
2433
|
if ($s->{template}{break}) { |
169
|
4
|
|
|
|
|
8
|
$s->{template}{break} = 0; |
170
|
4
|
|
|
|
|
7
|
last FOR; |
171
|
|
|
|
|
|
|
} |
172
|
1264
|
100
|
|
|
|
2661
|
if ($s->{template}{continue}) { |
173
|
19
|
|
|
|
|
24
|
$s->{template}{continue} = 0; |
174
|
19
|
|
|
|
|
37
|
next FOR; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
} |
178
|
107
|
|
|
|
|
280
|
return $return; |
179
|
|
|
|
|
|
|
} |
180
|
107
|
|
|
|
|
903
|
); |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
1; |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=pod |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=encoding UTF-8 |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=begin stopwords |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
Lütke jadedPixel iterable |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=end stopwords |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 NAME |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Template::Liquid::Tag::For - Simple loop construct |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=head1 Synopsis |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
{% for x in (1..10) %} |
201
|
|
|
|
|
|
|
x = {{ x }} |
202
|
|
|
|
|
|
|
{% endfor %} |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=head1 Description |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
For loops... uh, loop over collections. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head2 Loop-scope Variables |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
During every for loop, the following helper variables are available for extra |
211
|
|
|
|
|
|
|
styling needs: |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=over |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=item * C<forloop.length> |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
length of the entire for loop |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=item * C<forloop.index> |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
index of the current iteration |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=item * C<forloop.index0> |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
index of the current iteration (zero based) |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
=item * C<forloop.rindex> |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
how many items are still left? |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=item * C<forloop.rindex0> |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
how many items are still left? (zero based) |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=item * C<forloop.first> |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
is this the first iteration? |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=item * C<forloop.last> |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
is this the last iteration? |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=item * C<forloop.type> |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
are we looping through an C<ARRAY> or a C<HASH>? |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=back |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
=head2 Attributes |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
There are several attributes you can use to influence which items you receive |
252
|
|
|
|
|
|
|
in your loop: |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=over |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=item C<limit:int> |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
lets you restrict how many items you get. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=item C<offset:int> |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
lets you start the collection with the nth item. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=back |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# array = [1,2,3,4,5,6] |
267
|
|
|
|
|
|
|
{% for item in array limit:2 offset:2 %} |
268
|
|
|
|
|
|
|
{{ item }} |
269
|
|
|
|
|
|
|
{% endfor %} |
270
|
|
|
|
|
|
|
# results in 3,4 |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head3 Reversing the Loop |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
You can reverse the direction the loop works with the C<reversed> attribute. To |
275
|
|
|
|
|
|
|
comply with the Ruby lib's functionality, C<reversed> B<must> be the first |
276
|
|
|
|
|
|
|
attribute. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
{% for item in collection reversed %} {{item}} {% endfor %} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=head3 Sorting |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
You can sort the variable with the C<sorted> attribute. This is an extension |
283
|
|
|
|
|
|
|
beyond the scope of Liquid's syntax and thus incompatible but it's useful. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
{% for item in collection sorted %} {{item}} {% endfor %} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
If you are sorting a hash, the values are sorted by keys by default. You may |
288
|
|
|
|
|
|
|
decide to sort by values like so: |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
{% for item in hash sorted:value %} {{item.value}} {% endfor %} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
...or make the default obvious with... |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
{% for item in hash sorted:key %} {{item.key}} {% endfor %} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=head2 Numeric Ranges |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Instead of looping over an existing collection, you can define a range of |
299
|
|
|
|
|
|
|
numbers to loop through. The range can be defined by both literal and variable |
300
|
|
|
|
|
|
|
numbers: |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
# if item.quantity is 4... |
303
|
|
|
|
|
|
|
{% for i in (1..item.quantity) %} |
304
|
|
|
|
|
|
|
{{ i }} |
305
|
|
|
|
|
|
|
{% endfor %} |
306
|
|
|
|
|
|
|
# results in 1,2,3,4 |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=head2 Hashes |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
To deal with the possibility of looping through hash references, I have chosen |
311
|
|
|
|
|
|
|
to extend the Liquid Engine's functionality. When looping through a hash, each |
312
|
|
|
|
|
|
|
item is made a single key/value pair. The item's actual key and value are in |
313
|
|
|
|
|
|
|
the C<item.key> and C<item.value> variables. ...here's an example: |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# where var = {A => 1, B => 2, C => 3} |
316
|
|
|
|
|
|
|
{ {% for x in var %} |
317
|
|
|
|
|
|
|
{{ x.key }} => {{ x.value }}, |
318
|
|
|
|
|
|
|
{% endfor %} } |
319
|
|
|
|
|
|
|
# results in { A => 1, C => 3, B => 2, } |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
The C<forloop.type> variable will contain C<HASH> if the looped variable is a |
322
|
|
|
|
|
|
|
hashref. Also note that the keys/value pairs are left unsorted. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=head2 C<else> tag |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
The else tag allows us to do this: |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
{% for item in collection %} |
329
|
|
|
|
|
|
|
Item {{ forloop.index }}: {{ item.name }} |
330
|
|
|
|
|
|
|
{% else %} |
331
|
|
|
|
|
|
|
There is nothing in the collection. |
332
|
|
|
|
|
|
|
{% endfor %} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
The C<else> branch is executed whenever the for branch will never be executed |
335
|
|
|
|
|
|
|
(e.g. collection is blank or not an iterable or out of iteration scope). |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=for basis https://github.com/Shopify/liquid/pull/56 |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=head1 TODO |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
Since this is a customer facing template engine, Liquid should provide some way |
342
|
|
|
|
|
|
|
to limit L<ranges|Template::Liquid::Tag::For/"Numeric Ranges"> and/or depth to |
343
|
|
|
|
|
|
|
avoid (functionally) infinite loops with code like... |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
{% for w in (1..10000000000) %} |
346
|
|
|
|
|
|
|
{% for x in (1..10000000000) %} |
347
|
|
|
|
|
|
|
{% for y in (1..10000000000) %} |
348
|
|
|
|
|
|
|
{% for z in (1..10000000000) %} |
349
|
|
|
|
|
|
|
{{ 'own' | replace:'o','p' }} |
350
|
|
|
|
|
|
|
{%endfor%} |
351
|
|
|
|
|
|
|
{%endfor%} |
352
|
|
|
|
|
|
|
{%endfor%} |
353
|
|
|
|
|
|
|
{%endfor%} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head1 See Also |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
Liquid for Designers: http://wiki.github.com/tobi/liquid/liquid-for-designers |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
L<Template::Liquid|Template::Liquid/"Create your own filters">'s docs on custom |
360
|
|
|
|
|
|
|
filter creation |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
L<Template::Liquid::Tag::Break|Template::Liquid::Tag::Break> and |
363
|
|
|
|
|
|
|
L<Template::Liquid::Tag::Continue|Template::Liquid::Tag::Continue> |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
=head1 Author |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/ |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
CPAN ID: SANKO |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=head1 License and Legal |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
Copyright (C) 2009-2023 by Sanko Robinson E<lt>sanko@cpan.orgE<gt> |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under |
376
|
|
|
|
|
|
|
the terms of L<The Artistic License |
377
|
|
|
|
|
|
|
2.0|http://www.perlfoundation.org/artistic_license_2_0>. See the F<LICENSE> |
378
|
|
|
|
|
|
|
file included with this distribution or L<notes on the Artistic License |
379
|
|
|
|
|
|
|
2.0|http://www.perlfoundation.org/artistic_2_0_notes> for clarification. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
When separated from the distribution, all original POD documentation is covered |
382
|
|
|
|
|
|
|
by the L<Creative Commons Attribution-Share Alike 3.0 |
383
|
|
|
|
|
|
|
License|http://creativecommons.org/licenses/by-sa/3.0/us/legalcode>. See the |
384
|
|
|
|
|
|
|
L<clarification of the |
385
|
|
|
|
|
|
|
CCA-SA3.0|http://creativecommons.org/licenses/by-sa/3.0/us/>. |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=cut |