Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / i486-linux-gnu-thread-multi / Template / Plugin / Filter.pm
CommitLineData
3fea05b9 1#============================================================= -*-Perl-*-
2#
3# Template::Plugin::Filter
4#
5# DESCRIPTION
6# Template Toolkit module implementing a base class plugin
7# object which acts like a filter and can be used with the
8# FILTER directive.
9#
10# AUTHOR
11# Andy Wardley <abw@wardley.org>
12#
13# COPYRIGHT
14# Copyright (C) 2001-2009 Andy Wardley. All Rights Reserved.
15#
16# This module is free software; you can redistribute it and/or
17# modify it under the same terms as Perl itself.
18#
19#============================================================================
20
21package Template::Plugin::Filter;
22
23use strict;
24use warnings;
25use base 'Template::Plugin';
26use Scalar::Util 'weaken';
27
28
29our $VERSION = 1.38;
30our $DYNAMIC = 0 unless defined $DYNAMIC;
31
32
33sub new {
34 my ($class, $context, @args) = @_;
35 my $config = @args && ref $args[-1] eq 'HASH' ? pop(@args) : { };
36
37 # look for $DYNAMIC
38 my $dynamic;
39 {
40 no strict 'refs';
41 $dynamic = ${"$class\::DYNAMIC"};
42 }
43 $dynamic = $DYNAMIC unless defined $dynamic;
44
45 my $self = bless {
46 _CONTEXT => $context,
47 _DYNAMIC => $dynamic,
48 _ARGS => \@args,
49 _CONFIG => $config,
50 }, $class;
51
52 return $self->init($config)
53 || $class->error($self->error());
54}
55
56
57sub init {
58 my ($self, $config) = @_;
59 return $self;
60}
61
62
63sub factory {
64 my $self = shift;
65 my $this = $self;
66
67 # This causes problems: https://rt.cpan.org/Ticket/Display.html?id=46691
68 # If the plugin is loaded twice in different templates (one INCLUDEd into
69 # another) then the filter gets garbage collected when the inner template
70 # ends (at least, I think that's what's happening). So I'm going to take
71 # the "suck it and see" approach, comment it out, and wait for someone to
72 # complain that this module is leaking memory.
73
74 # weaken($this);
75
76 if ($self->{ _DYNAMIC }) {
77 return $self->{ _DYNAMIC_FILTER } ||= [ sub {
78 my ($context, @args) = @_;
79 my $config = ref $args[-1] eq 'HASH' ? pop(@args) : { };
80
81 return sub {
82 $this->filter(shift, \@args, $config);
83 };
84 }, 1 ];
85 }
86 else {
87 return $self->{ _STATIC_FILTER } ||= sub {
88 $this->filter(shift);
89 };
90 }
91}
92
93sub filter {
94 my ($self, $text, $args, $config) = @_;
95 return $text;
96}
97
98
99sub merge_config {
100 my ($self, $newcfg) = @_;
101 my $owncfg = $self->{ _CONFIG };
102 return $owncfg unless $newcfg;
103 return { %$owncfg, %$newcfg };
104}
105
106
107sub merge_args {
108 my ($self, $newargs) = @_;
109 my $ownargs = $self->{ _ARGS };
110 return $ownargs unless $newargs;
111 return [ @$ownargs, @$newargs ];
112}
113
114
115sub install_filter {
116 my ($self, $name) = @_;
117 $self->{ _CONTEXT }->define_filter( $name => $self->factory );
118 return $self;
119}
120
121
122
1231;
124
125__END__
126
127=head1 NAME
128
129Template::Plugin::Filter - Base class for plugin filters
130
131=head1 SYNOPSIS
132
133 package MyOrg::Template::Plugin::MyFilter;
134
135 use Template::Plugin::Filter;
136 use base qw( Template::Plugin::Filter );
137
138 sub filter {
139 my ($self, $text) = @_;
140
141 # ...mungify $text...
142
143 return $text;
144 }
145
146 # now load it...
147 [% USE MyFilter %]
148
149 # ...and use the returned object as a filter
150 [% FILTER $MyFilter %]
151 ...
152 [% END %]
153
154=head1 DESCRIPTION
155
156This module implements a base class for plugin filters. It hides
157the underlying complexity involved in creating and using filters
158that get defined and made available by loading a plugin.
159
160To use the module, simply create your own plugin module that is
161inherited from the C<Template::Plugin::Filter> class.
162
163 package MyOrg::Template::Plugin::MyFilter;
164
165 use Template::Plugin::Filter;
166 use base qw( Template::Plugin::Filter );
167
168Then simply define your C<filter()> method. When called, you get
169passed a reference to your plugin object (C<$self>) and the text
170to be filtered.
171
172 sub filter {
173 my ($self, $text) = @_;
174
175 # ...mungify $text...
176
177 return $text;
178 }
179
180To use your custom plugin, you have to make sure that the Template
181Toolkit knows about your plugin namespace.
182
183 my $tt2 = Template->new({
184 PLUGIN_BASE => 'MyOrg::Template::Plugin',
185 });
186
187Or for individual plugins you can do it like this:
188
189 my $tt2 = Template->new({
190 PLUGINS => {
191 MyFilter => 'MyOrg::Template::Plugin::MyFilter',
192 },
193 });
194
195Then you C<USE> your plugin in the normal way.
196
197 [% USE MyFilter %]
198
199The object returned is stored in the variable of the same name,
200'C<MyFilter>'. When you come to use it as a C<FILTER>, you should add
201a dollar prefix. This indicates that you want to use the filter
202stored in the variable 'C<MyFilter>' rather than the filter named
203'C<MyFilter>', which is an entirely different thing (see later for
204information on defining filters by name).
205
206 [% FILTER $MyFilter %]
207 ...text to be filtered...
208 [% END %]
209
210You can, of course, assign it to a different variable.
211
212 [% USE blat = MyFilter %]
213
214 [% FILTER $blat %]
215 ...text to be filtered...
216 [% END %]
217
218Any configuration parameters passed to the plugin constructor from the
219C<USE> directive are stored internally in the object for inspection by
220the C<filter()> method (or indeed any other method). Positional
221arguments are stored as a reference to a list in the C<_ARGS> item while
222named configuration parameters are stored as a reference to a hash
223array in the C<_CONFIG> item.
224
225For example, loading a plugin as shown here:
226
227 [% USE blat = MyFilter 'foo' 'bar' baz = 'blam' %]
228
229would allow the C<filter()> method to do something like this:
230
231 sub filter {
232 my ($self, $text) = @_;
233
234 my $args = $self->{ _ARGS }; # [ 'foo', 'bar' ]
235 my $conf = $self->{ _CONFIG }; # { baz => 'blam' }
236
237 # ...munge $text...
238
239 return $text;
240 }
241
242By default, plugins derived from this module will create static
243filters. A static filter is created once when the plugin gets
244loaded via the C<USE> directive and re-used for all subsequent
245C<FILTER> operations. That means that any argument specified with
246the C<FILTER> directive are ignored.
247
248Dynamic filters, on the other hand, are re-created each time
249they are used by a C<FILTER> directive. This allows them to act
250on any parameters passed from the C<FILTER> directive and modify
251their behaviour accordingly.
252
253There are two ways to create a dynamic filter. The first is to
254define a C<$DYNAMIC> class variable set to a true value.
255
256 package MyOrg::Template::Plugin::MyFilter;
257 use base 'Template::Plugin::Filter';
258 our $DYNAMIC = 1;
259
260The other way is to set the internal C<_DYNAMIC> value within the C<init()>
261method which gets called by the C<new()> constructor.
262
263 sub init {
264 my $self = shift;
265 $self->{ _DYNAMIC } = 1;
266 return $self;
267 }
268
269When this is set to a true value, the plugin will automatically
270create a dynamic filter. The outcome is that the C<filter()> method
271will now also get passed a reference to an array of postional
272arguments and a reference to a hash array of named parameters.
273
274So, using a plugin filter like this:
275
276 [% FILTER $blat 'foo' 'bar' baz = 'blam' %]
277
278would allow the C<filter()> method to work like this:
279
280 sub filter {
281 my ($self, $text, $args, $conf) = @_;
282
283 # $args = [ 'foo', 'bar' ]
284 # $conf = { baz => 'blam' }
285 }
286
287In this case can pass parameters to both the USE and FILTER directives,
288so your filter() method should probably take that into account.
289
290 [% USE MyFilter 'foo' wiz => 'waz' %]
291
292 [% FILTER $MyFilter 'bar' biz => 'baz' %]
293 ...
294 [% END %]
295
296You can use the C<merge_args()> and C<merge_config()> methods to do a quick
297and easy job of merging the local (e.g. C<FILTER>) parameters with the
298internal (e.g. C<USE>) values and returning new sets of conglomerated
299data.
300
301 sub filter {
302 my ($self, $text, $args, $conf) = @_;
303
304 $args = $self->merge_args($args);
305 $conf = $self->merge_config($conf);
306
307 # $args = [ 'foo', 'bar' ]
308 # $conf = { wiz => 'waz', biz => 'baz' }
309 ...
310 }
311
312You can also have your plugin install itself as a named filter by
313calling the C<install_filter()> method from the C<init()> method. You
314should provide a name for the filter, something that you might
315like to make a configuration option.
316
317 sub init {
318 my $self = shift;
319 my $name = $self->{ _CONFIG }->{ name } || 'myfilter';
320 $self->install_filter($name);
321 return $self;
322 }
323
324This allows the plugin filter to be used as follows:
325
326 [% USE MyFilter %]
327
328 [% FILTER myfilter %]
329 ...
330 [% END %]
331
332or
333
334 [% USE MyFilter name = 'swipe' %]
335
336 [% FILTER swipe %]
337 ...
338 [% END %]
339
340Alternately, you can allow a filter name to be specified as the
341first positional argument.
342
343 sub init {
344 my $self = shift;
345 my $name = $self->{ _ARGS }->[0] || 'myfilter';
346 $self->install_filter($name);
347 return $self;
348 }
349
350 [% USE MyFilter 'swipe' %]
351
352 [% FILTER swipe %]
353 ...
354 [% END %]
355
356=head1 EXAMPLE
357
358Here's a complete example of a plugin filter module.
359
360 package My::Template::Plugin::Change;
361 use Template::Plugin::Filter;
362 use base qw( Template::Plugin::Filter );
363
364 sub init {
365 my $self = shift;
366
367 $self->{ _DYNAMIC } = 1;
368
369 # first arg can specify filter name
370 $self->install_filter($self->{ _ARGS }->[0] || 'change');
371
372 return $self;
373 }
374
375 sub filter {
376 my ($self, $text, $args, $config) = @_;
377
378 $config = $self->merge_config($config);
379 my $regex = join('|', keys %$config);
380
381 $text =~ s/($regex)/$config->{ $1 }/ge;
382
383 return $text;
384 }
385
386 1;
387
388=head1 AUTHOR
389
390Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>
391
392=head1 COPYRIGHT
393
394Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
395
396This module is free software; you can redistribute it and/or
397modify it under the same terms as Perl itself.
398
399=head1 SEE ALSO
400
401L<Template::Plugin>, L<Template::Filters>, L<Template::Manual::Filters>
402
403=cut
404
405# Local Variables:
406# mode: perl
407# perl-indent-level: 4
408# indent-tabs-mode: nil
409# End:
410#
411# vim: expandtab shiftwidth=4: