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