File Coverage

lib/Templer/Plugin/Factory.pm
Criterion Covered Total %
statement 59 63 93.6
branch 16 20 80.0
condition 6 6 100.0
subroutine 14 15 93.3
pod 12 12 100.0
total 107 116 92.2


line stmt bran cond sub pod time code
1              
2             =head1 NAME
3            
4             Templer::Plugin::Factory - A simple plugin class
5            
6             =cut
7              
8             =head1 DESCRIPTION
9            
10             This class implements a singleton within which plugin classes may
11             be registered and retrieved.
12            
13             The plugins used by C<templer> are of two forms:
14            
15             =over 8
16            
17             =item formatters
18            
19             These plugins operate upon the text contained in L<Templer::Site::Page> objects
20             and transform the input into HTML.
21            
22             =item variable expanders
23            
24             These plugins, also operating on L<Templer::Site::Page> objects, are allowed
25             the opportunity to modify, update, replace, or delete the various per-page
26             variables.
27            
28             =back
29            
30             Plugins of each type register themselves by calling the appropriate methods
31             in this class.
32            
33             =cut
34              
35             =head1 LICENSE
36            
37             This module is free software; you can redistribute it and/or modify it
38             under the terms of either:
39            
40             a) the GNU General Public License as published by the Free Software
41             Foundation; either version 2, or (at your option) any later version,
42             or
43            
44             b) the Perl "Artistic License".
45            
46             =cut
47              
48             =head1 AUTHOR
49            
50             Steve Kemp <steve@steve.org.uk>
51            
52             =cut
53              
54             =head1 COPYRIGHT AND LICENSE
55            
56             Copyright (C) 2012-2015 Steve Kemp <steve@steve.org.uk>.
57            
58             This library is free software. You can modify and or distribute it under
59             the same terms as Perl itself.
60            
61             =cut
62              
63             =head1 METHODS
64            
65             =cut
66              
67              
68 11     11   92509 use strict;
  11         13  
  11         245  
69 11     11   32 use warnings;
  11         10  
  11         409  
70              
71              
72             package Templer::Plugin::Factory;
73              
74              
75             my $singleton;
76              
77              
78             #
79             # Look for plugins beneath the `Templer::Plugin` namespace.
80             #
81             use Module::Pluggable
82 11         56   search_path => ['Templer::Plugin'],
83 11     11   4295   require => 1;
  11         85383  
84              
85              
86             #
87             # Invoking `plugins` ensures that we've actually loaded our plugins
88             # by the time this module is loaded.
89             #
90             my @plugins = plugins();
91              
92              
93              
94              
95             =head2 new
96            
97             Constructor.
98            
99             This class is a singleton, so this method will either construct
100             an instance of this class or return the global instance.
101            
102             =cut
103              
104             sub new
105             {
106 190     190 1 5545     my $class = shift;
107 190   100     890     $singleton ||= bless {}, $class;
108             }
109              
110              
111              
112             =head2 load_plugins
113            
114             This method loads "*.pm" from the given directory.
115            
116             =cut
117              
118             sub load_plugins
119             {
120 0     0 1 0     my ( $self, $directory ) = (@_);
121 0 0       0     return unless ( -d $directory );
122              
123 0         0     foreach my $file ( sort( glob( $directory . "/*.pm" ) ) )
124                 {
125 0         0         require $file;
126                 }
127             }
128              
129              
130             =head2 init
131            
132             For each loaded plugin invoke the "init" method, if it exists.
133            
134             =cut
135              
136             sub init
137             {
138 2     2 1 4     my ( $self, $site ) = (@_);
139              
140 2         2     foreach my $plugin ( @{ $self->{ 'plugins' } } )
  2         7  
141                 {
142 20 100       86         if ( UNIVERSAL::can( $plugin, "init" ) )
143                     {
144 2         7             $plugin->init($site);
145                     }
146                 }
147             }
148              
149              
150             =head2 register_formatter
151            
152             This method should be called by all formatting plugins to register
153             themselves. The two arguments are the name of the input-format,
154             and the class-name which may be instantiated to process that kind
155             of input.
156            
157             L<Templer::Plugin::Textile> and L<Templer::Plugin::Markdown> are
158             example classes.
159            
160             =cut
161              
162             sub register_formatter
163             {
164 45     45 1 395     my ( $self, $name, $obj ) = (@_);
165              
166 45 50       85     die "No name" unless ($name);
167 45         59     $name = lc($name);
168 45         292     $self->{ 'formatters' }{ $name } = $obj;
169             }
170              
171              
172              
173             =head2 register_filter
174            
175             This method should be called by all template filter plugins to register
176             themselves. The two arguments are the name of the template-filter,
177             and the class-name which may be instantiated to process that kind
178             of input.
179            
180             L<Templer::Plugin::Dollar> and L<Templer::Plugin::Strict> are
181             example classes.
182            
183             =cut
184              
185             sub register_filter
186             {
187 22     22 1 38     my ( $self, $name, $obj ) = (@_);
188              
189 22 50       48     die "No name" unless ($name);
190 22         35     $name = lc($name);
191 22         161     $self->{ 'filters' }{ $name } = $obj;
192             }
193              
194              
195              
196             =head2 register_plugin
197            
198             This method should be called by all variable-expanding plugins to register
199             themselves. The expected argument is the class-name which may be instantiated
200             to expand variables.
201            
202             L<Templer::Plugin::ShellCommand>, L<Templer::Plugin::FileGlob>, and
203             L<Templer::Plugin::FileContents> are examples of such plugins.
204            
205             NOTE: The plugin is instantiated immediately, and kept alive for the duration
206             of a templer-run.
207            
208             =cut
209              
210             sub register_plugin
211             {
212 111     111 1 151     my ( $self, $obj ) = (@_);
213              
214 111         98     push( @{ $self->{ 'plugins' } }, $obj->new() );
  111         331  
215             }
216              
217              
218              
219             =head2 expand_variables
220            
221             Expand variables via all loaded plugins.
222            
223             =cut
224              
225             sub expand_variables
226             {
227 9     9 1 498     my ( $self, $site, $page, $data ) = (@_);
228              
229 9         11     my $out;
230              
231 9         12     foreach my $plugin ( @{ $self->{ 'plugins' } } )
  9         26  
232                 {
233 91 100       296         if ( UNIVERSAL::can( $plugin, "expand_variables" ) )
234                     {
235 82         298             my %in = %$data;
236 82         217             $out = $plugin->expand_variables( $site, $page, \%in );
237 82         278             $data = \%$out;
238                     }
239                 }
240 9         27     return ($data);
241             }
242              
243              
244              
245             =head2 cleanup
246            
247             For each loaded plugin invoke the "cleanup" method, if it exists.
248            
249             This can be useful if you wish a plugin to generate a site-map, or similar.
250            
251             =cut
252              
253             sub cleanup
254             {
255 2     2 1 4     my ($self) = (@_);
256              
257 2         2     foreach my $plugin ( @{ $self->{ 'plugins' } } )
  2         5  
258                 {
259 20 100       61         if ( UNIVERSAL::can( $plugin, "cleanup" ) )
260                     {
261 2         6             $plugin->cleanup();
262                     }
263                 }
264             }
265              
266              
267              
268             =head2 formatter
269            
270             Return a new instance of the formatter class with the given name.
271            
272             C<undef> is returned if no such plugin is registered.
273            
274             =cut
275              
276             sub formatter
277             {
278 29     29 1 19274     my ( $self, $name ) = (@_);
279              
280 29 100       75     die "No name" unless ($name);
281 27         33     $name = lc($name);
282              
283             #
284             # Lookup the formatter by name, if it is found
285             # then instantiate the clsee.
286             #
287 27   100     65     my $obj = $self->{ 'formatters' }{ $name } || undef;
288 27 100       101     $obj = $obj->new() if ($obj);
289              
290 27         81     return ($obj);
291             }
292              
293              
294              
295             =head2 formatters
296            
297             Return the names of each registered formatter-plugin, this is only
298             used by the test-suite.
299            
300             =cut
301              
302             sub formatters
303             {
304 3     3 1 1483     my ($self) = (@_);
305              
306 3         5     keys( %{ $self->{ 'formatters' } } );
  3         20  
307             }
308              
309              
310              
311             =head2 filter
312            
313             Return a new instance of the filter class with the given name.
314            
315             C<undef> is returned if no such plugin is registered.
316            
317             =cut
318              
319             sub filter
320             {
321 15     15 1 2752     my ( $self, $name ) = (@_);
322              
323 15 100       54     die "No name" unless ($name);
324 13         18     $name = lc($name);
325              
326             #
327             # Lookup the filter by name, if it is found
328             # then instantiate the class.
329             #
330 13   100     43     my $obj = $self->{ 'filters' }{ $name } || undef;
331 13 100       57     $obj = $obj->new() if ($obj);
332              
333 13         46     return ($obj);
334             }
335              
336              
337              
338             =head2 filters
339            
340             Return the names of each registered filter-plugin, this is only
341             used by the test-suite.
342            
343             =cut
344              
345             sub filters
346             {
347 1     1 1 596     my ($self) = (@_);
348              
349 1         2     keys( %{ $self->{ 'filters' } } );
  1         7  
350             }
351              
352              
353              
354             1;
355