File Coverage

blib/lib/CGI/FastTemplate.pm
Criterion Covered Total %
statement 93 147 63.2
branch 24 48 50.0
condition 1 3 33.3
subroutine 12 17 70.5
pod 13 16 81.2
total 143 231 61.9


line stmt bran cond sub pod time code
1              
2             ##################################################
3             ##
4             ## Name: CGI::FastTemplate
5             ##
6             ## Copyright (c) 1998-99 Jason Moore . All rights
7             ## reserved.
8             ##
9             ## This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself.
11             ##
12             ## This program is distributed in the hope that it will be useful,
13             ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14             ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15             ## Artistic License for more details.
16             ##
17             ##
18             ## Credits:
19             ## - fancy regexp taken from article by Brian Slesinsky
20             ## http://www.hotwired.com/webmonkey/code/97/21/index2a_page4.html?tw=perl
21             ##
22             ## - modified regexp to support ${VAR} and $VAR styles suggested by Eric L. Brine
23             ##
24             ##
25             ## Documentation:
26             ## See
27             ## 'perldoc CGI::FastTemplate'
28             ## or
29             ## 'perldoc ./FastTemplate'
30             ##
31             ## History:
32             ## See 'README'
33             ##
34             ## $Id: FastTemplate.pm,v 1.2 1999/06/27 02:12:23 jmoore Exp $
35             ##
36             ##################################################
37              
38             package CGI::FastTemplate;
39              
40 5     5   7131 use strict;
  5         11  
  5         22213  
41              
42             $CGI::FastTemplate::VERSION = '1.09';
43             $CGI::FastTemplate::ROOT = undef;
44              
45             $CGI::FastTemplate::VAR_ID = '$';
46             $CGI::FastTemplate::DELIM_LEFT = '{';
47             $CGI::FastTemplate::DELIM_RIGHT = '}';
48              
49             ##
50             ## define indexes for object attributes
51             ##
52              
53             sub STRICT () {0};
54             sub namespace () {1};
55             sub namespaces () {2};
56             sub last_parse () {3};
57             sub template_name () {4};
58             sub template_data () {5};
59             sub ROOT () {6};
60              
61              
62             ##################################################
63             ##
64             sub new
65             ##
66             ## - instantiates FastTemplate
67             ##
68             {
69 5     5 0 2289 my($class,$root) = @_;
70 5         17 my $self = [];
71 5         16 bless $self, $class;
72              
73 5         22 $self->init;
74              
75 5         11 $self->[STRICT] = 1;
76              
77 5 100       21 if (defined($root))
78             {
79 1         7 $self->set_root($root);
80             }
81 5         16 return($self);
82             }
83              
84             ##################################################
85             ##
86             sub strict
87             ##
88             {
89 2     2 1 14 my($self) = shift;
90 2         7 $self->[STRICT] = 1;
91             }
92              
93             ##################################################
94             ##
95             sub no_strict
96             ##
97             {
98 2     2 1 10 my($self) = shift;
99 2         6 $self->[STRICT] = undef;
100             }
101              
102             ##################################################
103             ##
104             sub clear_all
105             ##
106             ## - initializes (or clears!) variables
107             ##
108             {
109 5     5 1 14 my($self) = shift;
110              
111 5 50       22 if (!ref($self))
112             {
113 0         0 print STDERR "FastTemplate: Unable to call init without instance.\n";
114 0         0 return();
115             }
116              
117 5         32 $self->[namespace] = {}; ## main hash where we resolve variables
118 5         16 $self->[namespaces] = []; ## array of hash refs
119              
120 5         12 $self->[last_parse] = undef; ## remember where we stored the last parse so print()
121             ## will have a default
122              
123 5         12 $self->[template_name] = {}; ## template name: template file
124 5         19 $self->[template_data] = {}; ## template name: template content/data
125             }
126             *init = \&clear_all; ## alias to 'clear' : 'init'
127              
128             ##################################################
129             ##
130             sub clear_define
131             ##
132             ## - clears values entered with define()
133             ##
134             {
135 0     0 1 0 my($self) = shift;
136 0         0 $self->[template_name] = {};
137             }
138              
139             ##################################################
140             ##
141             sub clear_tpl
142             ##
143             ## - clears hash that holds loaded templates.
144             ## - if passed an array of names, clears only those loaded templates
145             ##
146             {
147 0     0 1 0 my($self) = shift;
148 0         0 my @args = @_;
149              
150 0 0       0 if (@args == 0) ## clear entire cache
151             {
152 0         0 $self->[template_data] = {};
153 0         0 return(1);
154             }
155              
156             ## clear just a selection of entries
157              
158 0         0 for (@args)
159             {
160 0         0 delete( ${$self->[template_data]}{$_} );
  0         0  
161             }
162              
163 0         0 return(1);
164             }
165              
166              
167             ##################################################
168             ##
169             sub clear_href
170             ##
171             ## - removes from the end, a given number of hash references
172             ## from the namespace list.
173             ##
174             ## - 1: number of hash references to erase
175             ##
176             {
177 0     0 1 0 my($self, $number) = @_;
178              
179 0 0       0 if (!defined($number))
180             {
181 0         0 $self->[namespaces] = [];
182 0         0 return(1);
183             }
184              
185 0         0 for (1..$number)
186             {
187 0         0 pop(@{$self->[namespaces]}); ## toss it away
  0         0  
188             }
189              
190 0         0 return(1);
191             }
192              
193             #################################################
194             ##
195             sub clear_parse
196             ##
197             ## - clears hash which holds parsed variables
198             ## - if called with a scalar only clears that key/element in the namespace.
199             ## so, $tpl->clear("ROWS") which is almost the same as,
200             ## $tpl->assign(ROWS => "");
201             ##
202             ## - if called with an array, all keys in the array are deleted
203             ## e.g. $tpl->clear("ROWS", "COLS"); has the same effect as
204             ## $tpl->assign(ROWS => "",
205             ## COLS => "");
206             ##
207             ##
208             {
209 0     0 1 0 my $self = shift;
210              
211 0 0       0 if (@_ == 0) ## clear everything
212             {
213 0         0 $self->[namespace] = {}; ## main hash where we resolve variables
214 0         0 $self->[last_parse] = undef; ## remember where we stored the last parse so print()
215 0         0 return(1);
216             }
217            
218 0         0 for (@_)
219             {
220 0         0 delete(${$self->[namespace]}{$_});
  0         0  
221             }
222 0         0 return(1);
223             }
224              
225             *clear = \&clear_parse; ## alias clear -> clear_parse
226              
227             ##################################################
228             ##
229             sub set_root
230             ##
231             ## - sets template root directory.
232             {
233 1     1 0 2 my($self, $root) = @_;
234              
235             ## set object default root directory
236              
237 1         2 $CGI::FastTemplate::ROOT = $root;
238              
239             ## set instance template dir
240             ##
241             ## - no needed
242             ##
243              
244 1 50       9 if (ref($self))
245             {
246 1         2 $self->[ROOT] = $root;
247             }
248              
249 1         2 return(1);
250             }
251              
252             ##################################################
253             ##
254             sub define
255             ##
256             ## - sets alias/name to associate with template filenames
257             ## - note: names are relative to ROOT directory (set with set_root)
258             ## - e.g. the following works
259             ## $tpl->set_root("/tmp/docs");
260             ## $tpl->define( main => "../dev_docs");
261             ## (assuming you have templates in /tmp/dev_docs)
262             ##
263             ## - files are not loaded until used, so go nuts when defining. each line
264             ## only costs a wee bit of memory and compile time.
265             ##
266             ## - note: define is cumulative
267             ##
268             {
269 1     1 1 8 my($self, %define) = @_;
270              
271 1         5 for (keys(%define))
272             {
273 2         6 $self->[template_name]->{$_} = $define{$_};
274             }
275              
276 1         3 return(1);
277             }
278              
279             ##################################################
280             ##
281             sub assign
282             ##
283             ## - assigns values of a HASH directly to internal namespace
284             ## HASH
285             ##
286             ## Args:
287             ## - 1: hash reference (to add to array of namespaces)
288             ## - 1: hash (to merge with main namespace hash)
289             ##
290             ## - returns: 1 on success
291             ##
292             {
293 7     7 1 46 my $self = shift;
294            
295 7 50       34 if (ref($_[0]) eq "HASH")
296             {
297 0         0 push(@{$self->[namespaces]}, $_[0]);
  0         0  
298 0         0 return(1);
299             }
300            
301 7         96 my %assign = @_;
302              
303 7         16 my($name,$value);
304 7         30 while ( ($name,$value) = each(%assign) )
305             {
306 14         56 $self->[namespace]->{$name} = $value;
307             }
308              
309 7         20 return(1);
310             }
311              
312              
313             ##################################################
314             ##
315             sub parse
316             ##
317             ## - parses a scalar to resolve/interpolate any variables
318             ## it finds.
319             ##
320             ## - 1: hash of what we are parse in TARGET:SOURCE form
321             ## NOTE: SOURCE with a "." as the first character get appended
322             ## to existing TARGET
323             ##
324             {
325 9     9 1 173 my($self, %parse) = @_;
326              
327 9         12 my $target;
328 9         26 for $target (keys(%parse))
329             {
330             ##
331             ## make all sources an array...
332             ##
333              
334 9 50       29 if (ref($parse{$target}) ne "ARRAY")
335             {
336 9         29 $parse{$target} = [$parse{$target}];
337             }
338              
339 9         13 my($p, $append);
340              
341 9         14 for $p (@{$parse{$target}})
  9         21  
342             {
343 9 100       51 if (substr($p,0,1) eq ".") ## detect append
344             {
345 5         5 $append = 1;
346 5         12 $p = substr($p, 1);
347             }
348              
349 9 50       46 if (!exists($self->[template_name]{$p}))
350             {
351 0         0 print STDERR "FastTemplate: Template alias: $p does not exist.\n";
352 0         0 next;
353             }
354              
355             ## load template if we need to
356              
357 9 100       31 if (!exists($self->[template_data]{$p}))
358             {
359 2         26 $self->slurp($self->[template_name]->{$p}, \$self->[template_data]->{$p} );
360             }
361              
362             ## copy SOURCE (template_data) to temp variable
363             ## (can't use namespace, since we might be appending to it.)
364              
365 9         38 my $temp_parse = $self->[template_data]->{$p};
366              
367             #########
368             ## parse
369             #########
370              
371 9         283 $temp_parse =~ s/\$(?:([A-Z][A-Z0-9_]+)|\{([A-Z][A-Z0-9_]+)\})/
372              
373 18         87 my $v = $self->[namespace]->{$+};
374              
375 18 100       45 if (!defined($v))
376             {
377             ## look in array of hash refs for value of variable
378 2         3 my $r;
379 2         4 for $r (@{$self->[namespaces]})
  2         5  
380             {
381 0 0       0 if (exists($$r{$+})) ## found it
382             {
383 0         0 $v = $$r{$+};
384 0         0 last;
385             }
386             }
387             }
388 18 100       41 if (!defined($v)) ## $v should be empty not undef, to prevent
389             { ## warnings under -w
390 2 100       7 if ($self->[STRICT])
391             {
392 1         56 print STDERR "[CGI::FastTemplate] Warning: no value found for variable: $+\n";
393 1         4 $v = '$' . $+; ## keep original variable name in output
394             }
395             else
396             {
397 1         3 $v = ""; ## remove variable name
398             }
399             }
400 18         74 $v;
401             /ge;
402              
403 9         21 $self->[last_parse] = $target;
404             ## assign temp to final TARGET
405              
406 9 100       29 if ($append)
407             {
408 5         36 $self->[namespace]->{$target} .= $temp_parse;
409             }
410             else
411             {
412 4         29 $self->[namespace]->{$target} = $temp_parse;
413             }
414             }
415             }
416             }
417              
418             ##################################################
419             ##
420             sub slurp
421             ##
422             ## - slurps (loads) in file into a scalar.
423             ## - cool trick to undef the end of line character
424             ## grabbed from some usenet posting. (don't remember)
425             ##
426             ## - i think the maximum file size is (2**32-1) approx. 2 megs.
427             ##
428             ## - 1: filename (minus path)
429             ## - 2: reference to put result in [optional]
430             ## returns: scalar
431             ##
432             ##
433             {
434 2     2 0 4 my($self, $filename, $ref) = @_;
435 2         4 my $temp;
436              
437 2 50 33     14 if (ref($self) && defined($self->[ROOT])) ## use instance ROOT
    0          
438             {
439 2         5 $filename = $self->[ROOT] . "/" . $filename;
440             }
441             elsif (defined($CGI::FastTemplate::ROOT)) ## use object ROOT
442             {
443 0         0 $filename = $CGI::FastTemplate::ROOT . "/" . $filename;
444             }
445              
446 2 50       79 if (!open(TEMPLATE, $filename))
447             {
448 0         0 print STDERR "FastTemplate: slurp: cannot open: $filename ($!)";
449 0         0 return();
450             }
451              
452             ## cool trick!
453              
454 2         9 local($/) = undef;
455 2         55 $temp =