File Coverage

blib/lib/HTML/Template/Extension.pm
Criterion Covered Total %
statement 194 238 81.5
branch 45 78 57.6
condition 18 42 42.8
subroutine 25 31 80.6
pod 8 13 61.5
total 290 402 72.1


line stmt bran cond sub pod time code
1             package HTML::Template::Extension;
2              
3             $VERSION = "0.26";
4 0     0 0 0 sub Version { $VERSION; }
5              
6 1     1   3462 use HTML::Template;
  1         17252  
  1         46  
7             @HTML::Template::Extension::ISA = qw(HTML::Template);
8              
9              
10              
11 1     1   11 use Carp;
  1         3  
  1         70  
12 1     1   21359 use Data::Dumper;
  1         12359  
  1         67  
13 1     1   845 use FileHandle;
  1         11953  
  1         6  
14 1     1   404 use vars qw($DEBUG $DEBUG_FILE_PATH);
  1         2  
  1         59  
15 1     1   5 use strict;
  1         2  
  1         1291  
16              
17             $DEBUG = 0;
18             $DEBUG_FILE_PATH = '/tmp/HTML-Template-Extension.debug.txt';
19              
20             my %fields =
21             (
22             plugins => {},
23             plugins_cid => {},
24             filename => undef,
25             scalarref=>undef,
26             arrayref=>undef,
27             filehandle=>undef,
28             filter_internal => [],
29             );
30            
31             my @fields_req = qw//;
32             my $DEBUG_FH;
33              
34             sub new
35             {
36 1     1 1 15 my $proto = shift;
37 1   33     9 my $class = ref($proto) || $proto;
38             # aggiungo il filtro
39 1         4 my $self = {};
40             # I like %TAG_NAME% syntax
41 1         5 push @_,('vanguard_compatibility_mode' => 1);
42             # no error if a tag present in html was not set
43 1         3 push @_,('die_on_bad_params' => 0);
44             # enable loop variable items
45 1         3 push @_,('loop_context_vars' => 1);
46             # if don't exists neither filename, nor filehandle, nor scalarref,
47             # nor arrayref, add an empty scalarref to correct init HTML::Template
48 1         8 my %check = @_;
49 1 0 33     5 push @_,('scalarref' => \'') unless ( exists $check{'filename'} ||
      33        
      0        
50             exists $check{'filehandle'} ||
51             exists $check{'scalarref'} ||
52             exists $check{'arrayref'});
53 1         4 bless $self,$class;
54 1         6 $self->_init_local(@_);
55             # $self->_loadDynamicModule;
56             # $self->_reloadFilter;
57 1         11 my $htmpl = $class->HTML::Template::new(@_);
58 1         935 foreach (keys(%{$htmpl})) {
  1         4  
59 4         10 $self->{$_} = $htmpl->{$_};
60             }
61 1         3 bless $self,$class;
62 1         9 return $self;
63             }
64              
65             sub _init_local {
66 1     1   2 my $self = shift;
67 1         5 my (%options) = @_;
68             # add plugins
69             # Assign default options
70 1         7 while (my ($key,$value) = each(%fields)) {
71 7   66     49 $self->{$key} = $self->{$key} || $value;
72             }
73             # add plugins
74 1         3 foreach (@{$options{plugins}}) {
  1         4  
75 1         5 $self->plugin_add($_);
76             }
77 1         4 delete $options{plugins};
78             # Assign options
79 1         6 while (my ($key,$value) = each(%options)) {
80 4         17 $self->{$key} = $value
81             }
82             # Check required params
83 1         4 foreach (@fields_req) {
84 0 0       0 croak "You must declare '$_' in " . ref($self) . "::new"
85             if (!defined $self->{$_});
86             }
87 1 50       5 $self->{DEBUG_FH} = new FileHandle ">>$DEBUG_FILE_PATH" if ($DEBUG);
88             #$self->push_filter;
89             }
90              
91             sub output {
92             # redefine standard output function
93 16     16 1 550 my $self = shift;
94 16         41 my %args = @_;
95 16 100       41 if ($self->{_auto_parse}) {
96 2         7 $self->reloadFile();
97             }
98 16 100       44 if (exists $args{as}) {
99             # delete old params settings
100 14         60 $self->SUPER::clear_params();
101 14         222 my %as = %{$args{as}};
  14         46  
102 14         38 foreach (keys %as) {
103 14         71 $self->SUPER::param($_ => $as{$_});
104             }
105             }
106 16         402 my $output = $self->SUPER::output(%args);
107 16 50       886 print {$self->{'DEBUG_FH'}} Data::Dumper::Dumper($self) if ($DEBUG);
  0         0  
108 16         59 return $output;
109             }
110              
111             sub html {
112 13     13 1 1722 my $self = shift;
113 13 50       31 my %args = (defined $_[0]) ? %{$_[0]} : ();
  13         53  
114 13 50       49 $self->{filename}= $_[1] if (defined $_[1]);
115 13 100 66     146 if ( defined $self->{filename}
      33        
      100        
116             && (
117             !defined $self->{options}->{filename}
118             || $self->{filename} ne $self->{options}->{filename}
119             )
120             || $self->{_auto_parse}
121             ) {
122 10         27 $self->reloadFile();
123             }
124 13         45 return $self->output('as' => \%args);
125             }
126              
127             sub filename {
128 1     1 1 6 my $s=shift;
129 1 50       4 if (@_) {
130 1         3 my $new_file = shift;
131 1 50       5 if ($s->{filename} ne $new_file) {
132 1         2 $s->{filename} = $new_file;
133             # reload local file
134 1         2 $s->{_auto_parse} = 1;
135             # remove other text storage
136 1         3 delete($s->{scalarref});
137 1         3 delete($s->{arrayref});
138 1         3 delete($s->{filehandle});
139             }
140             };
141 1         3 return $s->{filename};
142             }
143              
144             sub scalarref {
145 0     0 1 0 my $s=shift;
146 0 0       0 if (@_) {
147 0         0 $s->{scalarref} = shift;
148             # reload local file
149 0         0 $s->{_auto_parse} = 1;
150 0         0 delete($s->{filename});
151 0         0 delete($s->{options}->{filename});
152 0         0 delete($s->{arrayref});
153 0         0 delete($s->{filehandle});
154             };
155             # remove other text storage
156 0         0 return $s->{scalarref};
157             }
158              
159             sub arrayref {
160 0     0 1 0 my $s=shift;
161 0 0       0 if (@_) {
162 0         0 $s->{arrayref} = shift;
163             # reload local file
164 0         0 $s->{_auto_parse} = 1;
165             # remove other text storage
166 0         0 delete($s->{scalarref});
167 0         0 delete($s->{filename});
168 0         0 delete($s->{options}->{filename});
169 0         0 delete($s->{filehandle});
170             };
171 0         0 return $s->{arrayref};
172             }
173              
174             sub filehandle {
175 0     0 1 0 my $s=shift;
176 0 0       0 if (@_) {
177 0         0 $s->{filehandle} = shift;
178             # reload local file
179 0         0 $s->{_auto_parse} = 1;
180             # remove other text storage
181 0         0 delete($s->{scalarref});
182 0         0 delete($s->{arrayref});
183 0         0 delete($s->{filename});
184 0         0 delete($s->{options}->{filename});
185             };
186            
187 0         0 return $s->{filehandle};
188             }
189              
190             sub reloadFile {
191 12     12 0 21 my $self = shift;
192 12         19 $self->{_auto_parse} = 0;
193 12 100 66     110 if ( defined $self->{filename}
    100 33        
    50          
    50          
194             && ( !defined $self->{options}->{filename}
195             || $self->{filename} ne $self->{options}->{filename}
196             )
197             ) {
198 8         20 $self->{options}->{filename} = $self->{filename};
199 8         38 my $filepath = $self->_find_file($self->{filename});
200 8         343 $self->{options}->{filepath} = $self->{filename};
201             } elsif (exists($self->{scalarref})) {
202 1         3 $self->{options}->{scalarref} = $self->{scalarref};
203             } elsif (exists($self->{arrayref})) {
204 0         0 $self->{options}->{arrayref}=$self->{arrayref};
205             } elsif (exists($self->{filehandle})) {
206 0         0 $self->{options}->{filehandle} = $self->{filehandle};
207             }
208 12         26 $self->{filter} = $self->{filter_internal};
209 12         46 $self->{options}->{filter}= $self->{filter};
210 12         48 $self->_init_template();
211             # local caching params
212 12         85 my %params;
213 12         42 my @parname = $self->param();
214 12         108 foreach (@parname) {
215 11         29 $params{$_} = $self->param($_);
216             }
217 12         241 $self->_parse();
218             # reassign params
219 12         2868 foreach (keys(%params)) {
220 11         41 $self->param($_=> $params{$_});
221             }
222             # now that we have a full init, cache the structures if cacheing is
223             # on. shared cache is already cool.
224 12 50       314 if($self->{options}->{file_cache}){
225 0         0 $self->_commit_to_file_cache();
226             }
227 12 50 33     289 $self->_commit_to_cache() if (($self->{options}->{cache}
      33        
      33        
      33        
228             and not $self->{options}->{shared_cache}
229             and not $self->{options}->{file_cache}) or
230             ($self->{options}->{double_cache}) or
231             ($self->{options}->{double_file_cache}));
232             }
233              
234              
235             sub _reloadFilter {
236 2     2   3 my $self = shift;
237 2         7 undef $self->{filter_internal} ;
238 2         5 $self->{plugins_cid} = {};
239             # plugin priority filter
240             {
241 2         7 foreach (values %{$self->{plugins}}) {
  2         3  
  2         7  
242 6         15 $self->_pushModule($_);
243             }
244             }
245             }
246              
247             #sub _loadDynamicModule {
248             # my $self = shift;
249             # {
250             # foreach (keys %{$self->{plugins}}) {
251             # $self->_initModule($_);
252             # }
253             # }
254             #}
255              
256             sub _importModule {
257 8     8   12 my $self = shift;
258 8         12 my $module_name = shift;
259            
260 8         39 $module_name =~s/::/\//g;
261 8         6100 require $module_name . ".pm";
262             }
263              
264             sub _initModule {
265 9     9   14 my $self = shift;
266 9         11 my $module = shift;
267 9 100       24 if (ref($module) eq '') {
268 8         20 $self->_importModule($module);
269 1     1   5 no strict "refs";
  1         1  
  1         180  
270 8         20 &{$module . "::init"}($self);
  8         52  
271             } else {
272 1         7 $module->init($self);
273             }
274             }
275              
276             sub _pushModule {
277 15     15   24 my $self = shift;
278 15         41 my ($module, $module_name) = $self->_module_info(shift);
279 15 50       51 if (exists $self->{plugins_cid}->{$module_name}) {
280             # esiste gia' qualcosa di caricato...lo devo scaricare
281             # prima di poter fare qualsiasi cosa
282 0         0 my @code_ids = @{$self->{plugins_cid}->{$module_name}};
  0         0  
283 0         0 foreach (@code_ids) {
284 0         0 $self->_remove_filter_id($_);
285             }
286 0         0 delete $self->{plugins_cid}->{$module_name};
287             }
288             # count coderef items
289 15 100       36 my $pre_code_count = $self->{filter_internal} ? scalar(@{$self->{filter_internal}})-1 : -1 ;
  11         24  
290 15 100       31 if (ref($module) eq '') {
291 1     1   5 no strict "refs";
  1         3  
  1         523  
292 14         20 &{$module . "::push_filter"}($self);
  14         80  
293             } else {
294 1         6 $module->push_filter($self);
295             }
296             # count coderef items after push_filter
297 15 50       53 my $post_code_count = $self->{filter_internal} ? scalar(@{$self->{filter_internal}})-1 : -1;
  15         29  
298 15 100       38 return if ($post_code_count == $pre_code_count);
299 13 50       28 return if ($post_code_count <0);
300 13         16 $pre_code_count++;
301             # so this module as add post-pre code items
302 13 50       33 if (exists($self->{plugins_cid}->{$module_name})) {
303 0         0 push @{$self->{plugins_cid}->{$module_name}},($pre_code_count ..
  0         0  
304             $post_code_count)
305             } else {
306 13         66 $self->{plugins_cid}->{$module_name} = [$pre_code_count ..
307             $post_code_count];
308             }
309             }
310              
311              
312 0 0   0 1 0 sub filter { my $s=shift; return @_ ? ($s->{filter_internal}=shift) : $s->{filter_internal} }
  0         0  
313              
314             sub plugin_add {
315 9     9 0 2132 my $s = shift;
316 9 50       35 if (@_) {
317 9         26 my ($module, $module_name) = $s->_module_info(shift);
318             # plugin gia caricato
319 9 50       34 return if (exists $s->{plugins}->{$module_name});
320 9         25 $s->{plugins}->{$module_name} = $module;
321             # init module
322 9         27 $s->_initModule($module);
323             # add filter from added module to me
324 9         35 $s->_pushModule($module);
325             # add the array id of added code
326 9         21 $s->{_auto_parse} = 1;
327             };
328 9         29 return $s->{plugins}
329             }
330              
331             sub plugin_remove {
332 1     1 0 280 my $s = shift;
333 1         3 my ($module, $module_name) = $s->_module_info(shift);
334 1         4 delete $s->{plugins}->{$module_name};
335 1 50       5 if (exists $s->{plugins_cid}->{$module_name}) {
336 1         2 my @code_ids = @{$s->{plugins_cid}->{$module_name}};
  1         3  
337 1         3 foreach (@code_ids) {
338 1         3 $s->_remove_filter_id($_);
339             }
340             }
341 1         3 delete $s->{plugins_cid}->{$module_name};
342 1         4 $s->{_auto_parse} = 1;
343             }
344              
345             sub _remove_filter_id {
346 1     1   2 my $s = shift;
347 1         2 my $f_id = shift;
348 1         3 my @a = ();
349 1 50       3 push @a, @{$s->{filter_internal}}[0 .. $f_id-1] if ($f_id>0);
  0         0  
350 1         3 push @a, @{$s->{filter_internal}}[$f_id+1 .. $#{$s->{filter_internal}}]
  1         2  
  1         12  
351 1 50       2 if ($f_id< $#{$s->{filter_internal}});
352 1         5 $s->{filter_internal} = \@a;
353             }
354              
355             sub plugins_clear {
356 2     2 0 752 my $s = shift;
357 2         5 undef $s->{plugins};
358 2         5 undef $s->{options}->{plugins};
359 2         4 undef $s->{filter_internal};
360 2         4 $s->{plugins_cid} = {};
361 2         7 return $s->{plugins};
362             }
363              
364 0     0   0 sub DESTROY {
365             }
366              
367             sub AUTOLOAD {
368 10     10   3816 my $self = shift;
369 10         48 my @procs = split(/::/,$HTML::Template::Extension::AUTOLOAD);
370 10 50       29 return if (scalar(@procs)<3);
371 10         16 my $proc = $procs[-1];
372 10         12 my $value;
373 1     1   5 no strict "refs";
  1         1  
  1         168  
374 10         13 foreach my $module (values %{$self->{plugins}}) {
  10         33  
375 20         23 my $ret;
376 20 50       43 if (ref($module)) {
377             #$ret = eval { return $module->
378             } else {
379 20         25 $ret= eval { return &{"${module}::$proc"}($self,@_) };
  20         25  
  20         215  
380             }
381 20 100       435 if (!$@) { return $ret };
  10         172  
382             };
383             }
384              
385             sub _module_info {
386 25     25   38 my $self = shift;
387 25         50 my $module = shift;
388 25         31 my $module_name;
389 25 100       52 if (ref($module)) {
390 2         5 $module_name = ref($module);
391             } else {
392 23 100       114 $module = "HTML::Template::Extension::$module"
393             if ($module!~/::/);
394 23         29 $module_name = $module;
395             }
396 25         63 return ($module,$module_name);
397             }
398              
399              
400              
401             1;