Commit | Line | Data |
3fea05b9 |
1 | #============================================================= -*-Perl-*- |
2 | # |
3 | # Template::Filters |
4 | # |
5 | # DESCRIPTION |
6 | # Defines filter plugins as used by the FILTER directive. |
7 | # |
8 | # AUTHORS |
9 | # Andy Wardley <abw@wardley.org>, with a number of filters contributed |
10 | # by Leslie Michael Orchard <deus_x@nijacode.com> |
11 | # |
12 | # COPYRIGHT |
13 | # Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. |
14 | # |
15 | # This module is free software; you can redistribute it and/or |
16 | # modify it under the same terms as Perl itself. |
17 | # |
18 | #============================================================================ |
19 | |
20 | package Template::Filters; |
21 | |
22 | use strict; |
23 | use warnings; |
24 | use locale; |
25 | use base 'Template::Base'; |
26 | use Template::Constants; |
27 | use Scalar::Util 'blessed'; |
28 | |
29 | our $VERSION = 2.87; |
30 | our $AVAILABLE = { }; |
31 | our $TRUNCATE_LENGTH = 32; |
32 | our $TRUNCATE_ADDON = '...'; |
33 | |
34 | |
35 | #------------------------------------------------------------------------ |
36 | # standard filters, defined in one of the following forms: |
37 | # name => \&static_filter |
38 | # name => [ \&subref, $is_dynamic ] |
39 | # If the $is_dynamic flag is set then the sub-routine reference |
40 | # is called to create a new filter each time it is requested; if |
41 | # not set, then it is a single, static sub-routine which is returned |
42 | # for every filter request for that name. |
43 | #------------------------------------------------------------------------ |
44 | |
45 | our $FILTERS = { |
46 | # static filters |
47 | 'html' => \&html_filter, |
48 | 'html_para' => \&html_paragraph, |
49 | 'html_break' => \&html_para_break, |
50 | 'html_para_break' => \&html_para_break, |
51 | 'html_line_break' => \&html_line_break, |
52 | 'xml' => \&xml_filter, |
53 | 'uri' => \&uri_filter, |
54 | 'url' => \&url_filter, |
55 | 'upper' => sub { uc $_[0] }, |
56 | 'lower' => sub { lc $_[0] }, |
57 | 'ucfirst' => sub { ucfirst $_[0] }, |
58 | 'lcfirst' => sub { lcfirst $_[0] }, |
59 | 'stderr' => sub { print STDERR @_; return '' }, |
60 | 'trim' => sub { for ($_[0]) { s/^\s+//; s/\s+$// }; $_[0] }, |
61 | 'null' => sub { return '' }, |
62 | 'collapse' => sub { for ($_[0]) { s/^\s+//; s/\s+$//; s/\s+/ /g }; |
63 | $_[0] }, |
64 | |
65 | # dynamic filters |
66 | 'html_entity' => [ \&html_entity_filter_factory, 1 ], |
67 | 'indent' => [ \&indent_filter_factory, 1 ], |
68 | 'format' => [ \&format_filter_factory, 1 ], |
69 | 'truncate' => [ \&truncate_filter_factory, 1 ], |
70 | 'repeat' => [ \&repeat_filter_factory, 1 ], |
71 | 'replace' => [ \&replace_filter_factory, 1 ], |
72 | 'remove' => [ \&remove_filter_factory, 1 ], |
73 | 'eval' => [ \&eval_filter_factory, 1 ], |
74 | 'evaltt' => [ \&eval_filter_factory, 1 ], # alias |
75 | 'perl' => [ \&perl_filter_factory, 1 ], |
76 | 'evalperl' => [ \&perl_filter_factory, 1 ], # alias |
77 | 'redirect' => [ \&redirect_filter_factory, 1 ], |
78 | 'file' => [ \&redirect_filter_factory, 1 ], # alias |
79 | 'stdout' => [ \&stdout_filter_factory, 1 ], |
80 | }; |
81 | |
82 | # name of module implementing plugin filters |
83 | our $PLUGIN_FILTER = 'Template::Plugin::Filter'; |
84 | |
85 | |
86 | |
87 | #======================================================================== |
88 | # -- PUBLIC METHODS -- |
89 | #======================================================================== |
90 | |
91 | #------------------------------------------------------------------------ |
92 | # fetch($name, \@args, $context) |
93 | # |
94 | # Attempts to instantiate or return a reference to a filter sub-routine |
95 | # named by the first parameter, $name, with additional constructor |
96 | # arguments passed by reference to a list as the second parameter, |
97 | # $args. A reference to the calling Template::Context object is |
98 | # passed as the third paramter. |
99 | # |
100 | # Returns a reference to a filter sub-routine or a pair of values |
101 | # (undef, STATUS_DECLINED) or ($error, STATUS_ERROR) to decline to |
102 | # deliver the filter or to indicate an error. |
103 | #------------------------------------------------------------------------ |
104 | |
105 | sub fetch { |
106 | my ($self, $name, $args, $context) = @_; |
107 | my ($factory, $is_dynamic, $filter, $error); |
108 | |
109 | $self->debug("fetch($name, ", |
110 | defined $args ? ('[ ', join(', ', @$args), ' ]') : '<no args>', ', ', |
111 | defined $context ? $context : '<no context>', |
112 | ')') if $self->{ DEBUG }; |
113 | |
114 | # allow $name to be specified as a reference to |
115 | # a plugin filter object; any other ref is |
116 | # assumed to be a coderef and hence already a filter; |
117 | # non-refs are assumed to be regular name lookups |
118 | |
119 | if (ref $name) { |
120 | if (blessed($name) && $name->isa($PLUGIN_FILTER)) { |
121 | $factory = $name->factory() |
122 | || return $self->error($name->error()); |
123 | } |
124 | else { |
125 | return $name; |
126 | } |
127 | } |
128 | else { |
129 | return (undef, Template::Constants::STATUS_DECLINED) |
130 | unless ($factory = $self->{ FILTERS }->{ $name } |
131 | || $FILTERS->{ $name }); |
132 | } |
133 | |
134 | # factory can be an [ $code, $dynamic ] or just $code |
135 | if (ref $factory eq 'ARRAY') { |
136 | ($factory, $is_dynamic) = @$factory; |
137 | } |
138 | else { |
139 | $is_dynamic = 0; |
140 | } |
141 | |
142 | if (ref $factory eq 'CODE') { |
143 | if ($is_dynamic) { |
144 | # if the dynamic flag is set then the sub-routine is a |
145 | # factory which should be called to create the actual |
146 | # filter... |
147 | eval { |
148 | ($filter, $error) = &$factory($context, $args ? @$args : ()); |
149 | }; |
150 | $error ||= $@; |
151 | $error = "invalid FILTER for '$name' (not a CODE ref)" |
152 | unless $error || ref($filter) eq 'CODE'; |
153 | } |
154 | else { |
155 | # ...otherwise, it's a static filter sub-routine |
156 | $filter = $factory; |
157 | } |
158 | } |
159 | else { |
160 | $error = "invalid FILTER entry for '$name' (not a CODE ref)"; |
161 | } |
162 | |
163 | if ($error) { |
164 | return $self->{ TOLERANT } |
165 | ? (undef, Template::Constants::STATUS_DECLINED) |
166 | : ($error, Template::Constants::STATUS_ERROR) ; |
167 | } |
168 | else { |
169 | return $filter; |
170 | } |
171 | } |
172 | |
173 | |
174 | #------------------------------------------------------------------------ |
175 | # store($name, \&filter) |
176 | # |
177 | # Stores a new filter in the internal FILTERS hash. The first parameter |
178 | # is the filter name, the second a reference to a subroutine or |
179 | # array, as per the standard $FILTERS entries. |
180 | #------------------------------------------------------------------------ |
181 | |
182 | sub store { |
183 | my ($self, $name, $filter) = @_; |
184 | |
185 | $self->debug("store($name, $filter)") if $self->{ DEBUG }; |
186 | |
187 | $self->{ FILTERS }->{ $name } = $filter; |
188 | return 1; |
189 | } |
190 | |
191 | |
192 | #======================================================================== |
193 | # -- PRIVATE METHODS -- |
194 | #======================================================================== |
195 | |
196 | #------------------------------------------------------------------------ |
197 | # _init(\%config) |
198 | # |
199 | # Private initialisation method. |
200 | #------------------------------------------------------------------------ |
201 | |
202 | sub _init { |
203 | my ($self, $params) = @_; |
204 | |
205 | $self->{ FILTERS } = $params->{ FILTERS } || { }; |
206 | $self->{ TOLERANT } = $params->{ TOLERANT } || 0; |
207 | $self->{ DEBUG } = ( $params->{ DEBUG } || 0 ) |
208 | & Template::Constants::DEBUG_FILTERS; |
209 | |
210 | |
211 | return $self; |
212 | } |
213 | |
214 | |
215 | |
216 | #------------------------------------------------------------------------ |
217 | # _dump() |
218 | # |
219 | # Debug method |
220 | #------------------------------------------------------------------------ |
221 | |
222 | sub _dump { |
223 | my $self = shift; |
224 | my $output = "[Template::Filters] {\n"; |
225 | my $format = " %-16s => %s\n"; |
226 | my $key; |
227 | |
228 | foreach $key (qw( TOLERANT )) { |
229 | my $val = $self->{ $key }; |
230 | $val = '<undef>' unless defined $val; |
231 | $output .= sprintf($format, $key, $val); |
232 | } |
233 | |
234 | my $filters = $self->{ FILTERS }; |
235 | $filters = join('', map { |
236 | sprintf(" $format", $_, $filters->{ $_ }); |
237 | } keys %$filters); |
238 | $filters = "{\n$filters }"; |
239 | |
240 | $output .= sprintf($format, 'FILTERS (local)' => $filters); |
241 | |
242 | $filters = $FILTERS; |
243 | $filters = join('', map { |
244 | my $f = $filters->{ $_ }; |
245 | my ($ref, $dynamic) = ref $f eq 'ARRAY' ? @$f : ($f, 0); |
246 | sprintf(" $format", $_, $dynamic ? 'dynamic' : 'static'); |
247 | } sort keys %$filters); |
248 | $filters = "{\n$filters }"; |
249 | |
250 | $output .= sprintf($format, 'FILTERS (global)' => $filters); |
251 | |
252 | $output .= '}'; |
253 | return $output; |
254 | } |
255 | |
256 | |
257 | #======================================================================== |
258 | # -- STATIC FILTER SUBS -- |
259 | #======================================================================== |
260 | |
261 | #------------------------------------------------------------------------ |
262 | # uri_filter() [% FILTER uri %] |
263 | # |
264 | # URI escape a string. This code is borrowed from Gisle Aas' URI::Escape |
265 | # module, copyright 1995-2004. See RFC2396 for details. |
266 | #----------------------------------------------------------------------- |
267 | |
268 | # cache of escaped characters |
269 | our $URI_ESCAPES; |
270 | |
271 | sub uri_filter { |
272 | my $text = shift; |
273 | |
274 | $URI_ESCAPES ||= { |
275 | map { ( chr($_), sprintf("%%%02X", $_) ) } (0..255), |
276 | }; |
277 | |
278 | if ($] >= 5.008 && utf8::is_utf8($text)) { |
279 | utf8::encode($text); |
280 | } |
281 | |
282 | $text =~ s/([^A-Za-z0-9\-_.!~*'()])/$URI_ESCAPES->{$1}/eg; |
283 | $text; |
284 | } |
285 | |
286 | #------------------------------------------------------------------------ |
287 | # url_filter() [% FILTER uri %] |
288 | # |
289 | # NOTE: the difference: url vs uri. |
290 | # This implements the old-style, non-strict behaviour of the uri filter |
291 | # which allows any valid URL characters to pass through so that |
292 | # http://example.com/blah.html does not get the ':' and '/' characters |
293 | # munged. |
294 | #----------------------------------------------------------------------- |
295 | |
296 | sub url_filter { |
297 | my $text = shift; |
298 | |
299 | $URI_ESCAPES ||= { |
300 | map { ( chr($_), sprintf("%%%02X", $_) ) } (0..255), |
301 | }; |
302 | |
303 | if ($] >= 5.008 && utf8::is_utf8($text)) { |
304 | utf8::encode($text); |
305 | } |
306 | |
307 | $text =~ s/([^;\/?:@&=+\$,A-Za-z0-9\-_.!~*'()])/$URI_ESCAPES->{$1}/eg; |
308 | $text; |
309 | } |
310 | |
311 | |
312 | #------------------------------------------------------------------------ |
313 | # html_filter() [% FILTER html %] |
314 | # |
315 | # Convert any '<', '>' or '&' characters to the HTML equivalents, '<', |
316 | # '>' and '&', respectively. |
317 | #------------------------------------------------------------------------ |
318 | |
319 | sub html_filter { |
320 | my $text = shift; |
321 | for ($text) { |
322 | s/&/&/g; |
323 | s/</</g; |
324 | s/>/>/g; |
325 | s/"/"/g; |
326 | } |
327 | return $text; |
328 | } |
329 | |
330 | |
331 | #------------------------------------------------------------------------ |
332 | # xml_filter() [% FILTER xml %] |
333 | # |
334 | # Same as the html filter, but adds the conversion of ' to ' which |
335 | # is native to XML. |
336 | #------------------------------------------------------------------------ |
337 | |
338 | sub xml_filter { |
339 | my $text = shift; |
340 | for ($text) { |
341 | s/&/&/g; |
342 | s/</</g; |
343 | s/>/>/g; |
344 | s/"/"/g; |
345 | s/'/'/g; |
346 | } |
347 | return $text; |
348 | } |
349 | |
350 | |
351 | #------------------------------------------------------------------------ |
352 | # html_paragraph() [% FILTER html_para %] |
353 | # |
354 | # Wrap each paragraph of text (delimited by two or more newlines) in the |
355 | # <p>...</p> HTML tags. |
356 | #------------------------------------------------------------------------ |
357 | |
358 | sub html_paragraph { |
359 | my $text = shift; |
360 | return "<p>\n" |
361 | . join("\n</p>\n\n<p>\n", split(/(?:\r?\n){2,}/, $text)) |
362 | . "</p>\n"; |
363 | } |
364 | |
365 | |
366 | #------------------------------------------------------------------------ |
367 | # html_para_break() [% FILTER html_para_break %] |
368 | # |
369 | # Join each paragraph of text (delimited by two or more newlines) with |
370 | # <br><br> HTML tags. |
371 | #------------------------------------------------------------------------ |
372 | |
373 | sub html_para_break { |
374 | my $text = shift; |
375 | $text =~ s|(\r?\n){2,}|$1<br />$1<br />$1|g; |
376 | return $text; |
377 | } |
378 | |
379 | #------------------------------------------------------------------------ |
380 | # html_line_break() [% FILTER html_line_break %] |
381 | # |
382 | # replaces any newlines with <br> HTML tags. |
383 | #------------------------------------------------------------------------ |
384 | |
385 | sub html_line_break { |
386 | my $text = shift; |
387 | $text =~ s|(\r?\n)|<br />$1|g; |
388 | return $text; |
389 | } |
390 | |
391 | #======================================================================== |
392 | # -- DYNAMIC FILTER FACTORIES -- |
393 | #======================================================================== |
394 | |
395 | #------------------------------------------------------------------------ |
396 | # html_entity_filter_factory(\%options) [% FILTER html %] |
397 | # |
398 | # Dynamic version of the static html filter which attempts to locate the |
399 | # Apache::Util or HTML::Entities modules to perform full entity encoding |
400 | # of the text passed. Returns an exception if one or other of the |
401 | # modules can't be located. |
402 | #------------------------------------------------------------------------ |
403 | |
404 | sub use_html_entities { |
405 | require HTML::Entities; |
406 | return ($AVAILABLE->{ HTML_ENTITY } = \&HTML::Entities::encode_entities); |
407 | } |
408 | |
409 | sub use_apache_util { |
410 | require Apache::Util; |
411 | Apache::Util::escape_html(''); # TODO: explain this |
412 | return ($AVAILABLE->{ HTML_ENTITY } = \&Apache::Util::escape_html); |
413 | } |
414 | |
415 | sub html_entity_filter_factory { |
416 | my $context = shift; |
417 | my $haz; |
418 | |
419 | # if Apache::Util is installed then we use escape_html |
420 | $haz = $AVAILABLE->{ HTML_ENTITY } |
421 | || eval { use_apache_util() } |
422 | || eval { use_html_entities() } |
423 | || -1; # we use -1 for "not available" because it's a true value |
424 | |
425 | return ref $haz eq 'CODE' |
426 | ? $haz |
427 | : (undef, Template::Exception->new( |
428 | html_entity => 'cannot locate Apache::Util or HTML::Entities' ) |
429 | ); |
430 | } |
431 | |
432 | |
433 | #------------------------------------------------------------------------ |
434 | # indent_filter_factory($pad) [% FILTER indent(pad) %] |
435 | # |
436 | # Create a filter to indent text by a fixed pad string or when $pad is |
437 | # numerical, a number of space. |
438 | #------------------------------------------------------------------------ |
439 | |
440 | sub indent_filter_factory { |
441 | my ($context, $pad) = @_; |
442 | $pad = 4 unless defined $pad; |
443 | $pad = ' ' x $pad if $pad =~ /^\d+$/; |
444 | |
445 | return sub { |
446 | my $text = shift; |
447 | $text = '' unless defined $text; |
448 | $text =~ s/^/$pad/mg; |
449 | return $text; |
450 | } |
451 | } |
452 | |
453 | #------------------------------------------------------------------------ |
454 | # format_filter_factory() [% FILTER format(format) %] |
455 | # |
456 | # Create a filter to format text according to a printf()-like format |
457 | # string. |
458 | #------------------------------------------------------------------------ |
459 | |
460 | sub format_filter_factory { |
461 | my ($context, $format) = @_; |
462 | $format = '%s' unless defined $format; |
463 | |
464 | return sub { |
465 | my $text = shift; |
466 | $text = '' unless defined $text; |
467 | return join("\n", map{ sprintf($format, $_) } split(/\n/, $text)); |
468 | } |
469 | } |
470 | |
471 | |
472 | #------------------------------------------------------------------------ |
473 | # repeat_filter_factory($n) [% FILTER repeat(n) %] |
474 | # |
475 | # Create a filter to repeat text n times. |
476 | #------------------------------------------------------------------------ |
477 | |
478 | sub repeat_filter_factory { |
479 | my ($context, $iter) = @_; |
480 | $iter = 1 unless defined $iter and length $iter; |
481 | |
482 | return sub { |
483 | my $text = shift; |
484 | $text = '' unless defined $text; |
485 | return join('\n', $text) x $iter; |
486 | } |
487 | } |
488 | |
489 | |
490 | #------------------------------------------------------------------------ |
491 | # replace_filter_factory($s, $r) [% FILTER replace(search, replace) %] |
492 | # |
493 | # Create a filter to replace 'search' text with 'replace' |
494 | #------------------------------------------------------------------------ |
495 | |
496 | sub replace_filter_factory { |
497 | my ($context, $search, $replace) = @_; |
498 | $search = '' unless defined $search; |
499 | $replace = '' unless defined $replace; |
500 | |
501 | return sub { |
502 | my $text = shift; |
503 | $text = '' unless defined $text; |
504 | $text =~ s/$search/$replace/g; |
505 | return $text; |
506 | } |
507 | } |
508 | |
509 | |
510 | #------------------------------------------------------------------------ |
511 | # remove_filter_factory($text) [% FILTER remove(text) %] |
512 | # |
513 | # Create a filter to remove 'search' string from the input text. |
514 | #------------------------------------------------------------------------ |
515 | |
516 | sub remove_filter_factory { |
517 | my ($context, $search) = @_; |
518 | |
519 | return sub { |
520 | my $text = shift; |
521 | $text = '' unless defined $text; |
522 | $text =~ s/$search//g; |
523 | return $text; |
524 | } |
525 | } |
526 | |
527 | |
528 | #------------------------------------------------------------------------ |
529 | # truncate_filter_factory($n) [% FILTER truncate(n) %] |
530 | # |
531 | # Create a filter to truncate text after n characters. |
532 | #------------------------------------------------------------------------ |
533 | |
534 | sub truncate_filter_factory { |
535 | my ($context, $len, $char) = @_; |
536 | $len = $TRUNCATE_LENGTH unless defined $len; |
537 | $char = $TRUNCATE_ADDON unless defined $char; |
538 | |
539 | # Length of char is the minimum length |
540 | my $lchar = length $char; |
541 | if ($len < $lchar) { |
542 | $char = substr($char, 0, $len); |
543 | $lchar = $len; |
544 | } |
545 | |
546 | return sub { |
547 | my $text = shift; |
548 | return $text if length $text <= $len; |
549 | return substr($text, 0, $len - $lchar) . $char; |
550 | |
551 | |
552 | } |
553 | } |
554 | |
555 | |
556 | #------------------------------------------------------------------------ |
557 | # eval_filter_factory [% FILTER eval %] |
558 | # |
559 | # Create a filter to evaluate template text. |
560 | #------------------------------------------------------------------------ |
561 | |
562 | sub eval_filter_factory { |
563 | my $context = shift; |
564 | |
565 | return sub { |
566 | my $text = shift; |
567 | $context->process(\$text); |
568 | } |
569 | } |
570 | |
571 | |
572 | #------------------------------------------------------------------------ |
573 | # perl_filter_factory [% FILTER perl %] |
574 | # |
575 | # Create a filter to process Perl text iff the context EVAL_PERL flag |
576 | # is set. |
577 | #------------------------------------------------------------------------ |
578 | |
579 | sub perl_filter_factory { |
580 | my $context = shift; |
581 | my $stash = $context->stash; |
582 | |
583 | return (undef, Template::Exception->new('perl', 'EVAL_PERL is not set')) |
584 | unless $context->eval_perl(); |
585 | |
586 | return sub { |
587 | my $text = shift; |
588 | local($Template::Perl::context) = $context; |
589 | local($Template::Perl::stash) = $stash; |
590 | my $out = eval <<EOF; |
591 | package Template::Perl; |
592 | \$stash = \$context->stash(); |
593 | $text |
594 | EOF |
595 | $context->throw($@) if $@; |
596 | return $out; |
597 | } |
598 | } |
599 | |
600 | |
601 | #------------------------------------------------------------------------ |
602 | # redirect_filter_factory($context, $file) [% FILTER redirect(file) %] |
603 | # |
604 | # Create a filter to redirect the block text to a file. |
605 | #------------------------------------------------------------------------ |
606 | |
607 | sub redirect_filter_factory { |
608 | my ($context, $file, $options) = @_; |
609 | my $outpath = $context->config->{ OUTPUT_PATH }; |
610 | |
611 | return (undef, Template::Exception->new('redirect', |
612 | 'OUTPUT_PATH is not set')) |
613 | unless $outpath; |
614 | |
615 | $context->throw('redirect', "relative filenames are not supported: $file") |
616 | if $file =~ m{(^|/)\.\./}; |
617 | |
618 | $options = { binmode => $options } unless ref $options; |
619 | |
620 | sub { |
621 | my $text = shift; |
622 | my $outpath = $context->config->{ OUTPUT_PATH } |
623 | || return ''; |
624 | $outpath .= "/$file"; |
625 | my $error = Template::_output($outpath, \$text, $options); |
626 | die Template::Exception->new('redirect', $error) |
627 | if $error; |
628 | return ''; |
629 | } |
630 | } |
631 | |
632 | |
633 | #------------------------------------------------------------------------ |
634 | # stdout_filter_factory($context, $binmode) [% FILTER stdout(binmode) %] |
635 | # |
636 | # Create a filter to print a block to stdout, with an optional binmode. |
637 | #------------------------------------------------------------------------ |
638 | |
639 | sub stdout_filter_factory { |
640 | my ($context, $options) = @_; |
641 | |
642 | $options = { binmode => $options } unless ref $options; |
643 | |
644 | sub { |
645 | my $text = shift; |
646 | binmode(STDOUT) if $options->{ binmode }; |
647 | print STDOUT $text; |
648 | return ''; |
649 | } |
650 | } |
651 | |
652 | |
653 | 1; |
654 | |
655 | __END__ |
656 | |
657 | =head1 NAME |
658 | |
659 | Template::Filters - Post-processing filters for template blocks |
660 | |
661 | =head1 SYNOPSIS |
662 | |
663 | use Template::Filters; |
664 | |
665 | $filters = Template::Filters->new(\%config); |
666 | |
667 | ($filter, $error) = $filters->fetch($name, \@args, $context); |
668 | |
669 | if ($filter) { |
670 | print &$filter("some text"); |
671 | } |
672 | else { |
673 | print "Could not fetch $name filter: $error\n"; |
674 | } |
675 | |
676 | =head1 DESCRIPTION |
677 | |
678 | The C<Template::Filters> module implements a provider for creating subroutines |
679 | that implement the standard filters. Additional custom filters may be provided |
680 | via the L<FILTERS> configuration option. |
681 | |
682 | =head1 METHODS |
683 | |
684 | =head2 new(\%params) |
685 | |
686 | Constructor method which instantiates and returns a reference to a |
687 | C<Template::Filters> object. A reference to a hash array of configuration |
688 | items may be passed as a parameter. These are described below. |
689 | |
690 | my $filters = Template::Filters->new({ |
691 | FILTERS => { ... }, |
692 | }); |
693 | |
694 | my $template = Template->new({ |
695 | LOAD_FILTERS => [ $filters ], |
696 | }); |
697 | |
698 | A default C<Template::Filters> module is created by the L<Template> module |
699 | if the L<LOAD_FILTERS> option isn't specified. All configuration parameters |
700 | are forwarded to the constructor. |
701 | |
702 | $template = Template->new({ |
703 | FILTERS => { ... }, |
704 | }); |
705 | |
706 | =head2 fetch($name, \@args, $context) |
707 | |
708 | Called to request that a filter of a given name be provided. The name |
709 | of the filter should be specified as the first parameter. This should |
710 | be one of the standard filters or one specified in the L<FILTERS> |
711 | configuration hash. The second argument should be a reference to an |
712 | array containing configuration parameters for the filter. This may be |
713 | specified as 0, or undef where no parameters are provided. The third |
714 | argument should be a reference to the current L<Template::Context> |
715 | object. |
716 | |
717 | The method returns a reference to a filter sub-routine on success. It |
718 | may also return C<(undef, STATUS_DECLINE)> to decline the request, to allow |
719 | delegation onto other filter providers in the L<LOAD_FILTERS> chain of |
720 | responsibility. On error, C<($error, STATUS_ERROR)> is returned where $error |
721 | is an error message or L<Template::Exception> object indicating the error |
722 | that occurred. |
723 | |
724 | When the C<TOLERANT> option is set, errors are automatically downgraded to |
725 | a C<STATUS_DECLINE> response. |
726 | |
727 | =head2 use_html_entities() |
728 | |
729 | This class method can be called to configure the C<html_entity> filter to use |
730 | the L<HTML::Entities> module. An error will be raised if it is not installed |
731 | on your system. |
732 | |
733 | use Template::Filters; |
734 | Template::Filters->use_html_entities(); |
735 | |
736 | =head2 use_apache_util() |
737 | |
738 | This class method can be called to configure the C<html_entity> filter to use |
739 | the L<Apache::Util> module. An error will be raised if it is not installed on |
740 | your system. |
741 | |
742 | use Template::Filters; |
743 | Template::Filters->use_apache_util(); |
744 | |
745 | =head1 CONFIGURATION OPTIONS |
746 | |
747 | The following list summarises the configuration options that can be provided |
748 | to the C<Template::Filters> L<new()> constructor. Please see |
749 | L<Template::Manual::Config> for further information about each option. |
750 | |
751 | =head2 FILTERS |
752 | |
753 | The L<FILTERS|Template::Manual::Config#FILTERS> option can be used to specify |
754 | custom filters which can then be used with the |
755 | L<FILTER|Template::Manual::Directives#FILTER> directive like any other. These |
756 | are added to the standard filters which are available by default. |
757 | |
758 | $filters = Template::Filters->new({ |
759 | FILTERS => { |
760 | 'sfilt1' => \&static_filter, |
761 | 'dfilt1' => [ \&dyanamic_filter_factory, 1 ], |
762 | }, |
763 | }); |
764 | |
765 | =head2 TOLERANT |
766 | |
767 | The L<TOLERANT|Template::Manual::Config#TOLERANT> flag can be set to indicate |
768 | that the C<Template::Filters> module should ignore any errors and instead |
769 | return C<STATUS_DECLINED>. |
770 | |
771 | =head2 DEBUG |
772 | |
773 | The L<DEBUG|Template::Manual::Config#DEBUG> option can be used to enable |
774 | debugging messages for the Template::Filters module by setting it to include |
775 | the C<DEBUG_FILTERS> value. |
776 | |
777 | use Template::Constants qw( :debug ); |
778 | |
779 | my $template = Template->new({ |
780 | DEBUG => DEBUG_FILTERS | DEBUG_PLUGINS, |
781 | }); |
782 | |
783 | =head1 STANDARD FILTERS |
784 | |
785 | Please see L<Template::Manual::Filters> for a list of the filters provided |
786 | with the Template Toolkit, complete with examples of use. |
787 | |
788 | =head1 AUTHOR |
789 | |
790 | Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/> |
791 | |
792 | =head1 COPYRIGHT |
793 | |
794 | Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved. |
795 | |
796 | This module is free software; you can redistribute it and/or |
797 | modify it under the same terms as Perl itself. |
798 | |
799 | =head1 SEE ALSO |
800 | |
801 | L<Template::Manual::Filters>, L<Template>, L<Template::Context> |
802 | |
803 | =cut |
804 | |
805 | # Local Variables: |
806 | # mode: perl |
807 | # perl-indent-level: 4 |
808 | # indent-tabs-mode: nil |
809 | # End: |
810 | # |
811 | # vim: expandtab shiftwidth=4: |