File Coverage

blib/lib/TRD/Velocity.pm
Criterion Covered Total %
statement 145 173 83.8
branch 36 62 58.0
condition 1 3 33.3
subroutine 11 13 84.6
pod 11 11 100.0
total 204 262 77.8


line stmt bran cond sub pod time code
1             package TRD::Velocity;
2              
3             #use warnings;
4 2     2   51808 use strict;
  2         6  
  2         12998  
5              
6             =head1 NAME
7              
8             TRD::Velocity - Template engine
9              
10             =head1 VERSION
11              
12             Version 0.0.8
13              
14             =cut
15              
16             our $VERSION = '0.0.8';
17             our $debug = 0;
18              
19             =head1 SYNOPSIS
20              
21             use TRD::Velocity;
22              
23             $velo = new TRD::Velocity;
24             $velo->setTemplateFile( 'foo.html' );
25             $velo->set( 'name', 'value' );
26             $html_stmt = $velo->marge();
27             $ct = length( $html_stmt );
28             print "Content-Type: text/html\n";
29             print "Content-Length: ${ct}\n";
30             print "\n";
31             print $html_stmt;
32              
33             =head1 EXPORT
34              
35             A list of functions that can be exported. You can delete this section
36             if you don't export anything, such as for a purely object-oriented module.
37              
38             =head1 FUNCTIONS
39              
40             =head2 new
41              
42             new Constructor.
43              
44             my $velo = new TRD::Velocity;
45              
46             =cut
47             #======================================================================
48             sub new {
49 6     6 1 2336 my $pkg = shift;
50 6         42 bless {
51             params => undef,
52             templateFile => undef,
53             templateData => '',
54             contents => '',
55             command => '',
56             elsecommand => '',
57             options => undef,
58             }, $pkg;
59             };
60              
61             =head2 set( , )
62              
63             set parameter.
64              
65             $velo->set( 'itemname', 'Apple' );
66              
67             =cut
68             #======================================================================
69             sub set {
70 6     6 1 64 my $self = shift;
71 6         6 my $name = shift;
72 6         7 my $value = shift;
73              
74 6         21 $self->{params}->{$name} = $value;
75             }
76              
77             =head2 setTemplateFile( )
78              
79             set Template file.
80              
81             $velo->setTemplateFile( './template/soldmail.txt' );
82              
83             =cut
84             #======================================================================
85             sub setTemplateFile {
86 0     0 1 0 my $self = shift;
87 0         0 my $templateFile = shift;
88 0         0 my $fdata;
89              
90 0         0 $self->{templateFile} = $templateFile;
91              
92 0 0       0 open( my $fh, '<', $self->{templateFile} )|| die $!;
93 0         0 while( <$fh> ){
94 0         0 $fdata .= $_;
95             }
96 0         0 close( $fh );
97              
98 0         0 $self->{templateData} = $fdata;
99             }
100              
101             =head2 setTemplateData( )
102              
103             set Template data.
104              
105             my $template =<
106             Sender: ${sender}
107             Email: ${email}
108             EOT
109             $velo->setTemplateData( $template );
110             =cut
111             #======================================================================
112             sub setTemplateData {
113 6     6 1 27 my $self = shift;
114 6         8 my $templateData = shift;
115              
116 6         17 $self->{templateFile} = undef;
117              
118 6         14 $self->{templateData} = $templateData;
119             }
120              
121             =head2 marge
122              
123             Marge template to parameters.
124              
125             my $doc = $velo->marge();
126              
127             =cut
128             #======================================================================
129             sub marge {
130 6     6 1 20 my $self = shift;
131 6         7 my $contents;
132              
133 6         9 $contents = $self->{templateData};
134              
135 6 50       14 if( $debug ){
136 0         0 $contents =~s/([\t| ]*##.*)\n/\n/g;
137             } else {
138 6         12 $contents =~s/[\t| ]*##.*\n//g;
139             }
140              
141 6         13 $contents = $self->tag_handler( $contents );
142 6         14 $contents =~s/\${([\w\.-\[\]]+)}\.escape\(\)/$self->marge_val( $1. '.escape()' )/egos;
  1         5  
143 6         12 $contents =~s/\${([\w\.-\[\]]+)}\.unescape\(\)/$self->marge_val( $1. '.unescape()' )/egos;
  1         4  
144 6         25 $contents =~s/\${([\w\.-\[\]]+)}/$self->marge_val( $1 )/egos;
  12         33  
145              
146 6         19 $contents;
147             }
148              
149             =head2 tag_handler
150              
151             private function.
152              
153             =cut
154             #======================================================================
155             sub tag_handler {
156 6     6 1 7 my $self = shift;
157 6         12 $self->{contents} = shift;
158 6         7 my( $htm, $tag, $contents );
159 0         0 my @s;
160              
161 6         7 $contents = '';
162 6         16 while( $self->{contents} ne '' ){
163             #( $htm, $tag, $self->{contents} ) = split( /(#if|#foreach)/is, $self->{contents}, 2 );
164 8         59 @s = split( /(#if|#foreach)/is, $self->{contents}, 2 );
165 8 100       22 if( scalar( @s ) >= 3 ){
166 2         4 $self->{contents} = $s[2];
167             } else {
168 6         12 $self->{contents} = '';
169             }
170 8 100       20 if( scalar( @s ) >= 2 ){
171 2         3 $tag = $s[1];
172             #if( defined $tag ){
173 2 100       8 if( $tag eq '#if' ){
    50          
174 1         3 $self->if_sub();
175             } elsif( $tag eq '#foreach' ){
176 1         3 $self->foreach_sub();
177             }
178             }
179 8 50       20 if( scalar( @s ) >= 1 ){
180 8         12 $htm = $s[0];
181             #if( defined $htm ){
182 8         29 $contents .= $htm;
183             }
184             }
185              
186 6         14 $contents;
187             }
188              
189             =head2 if_sub
190              
191             private function.
192              
193             =cut
194             #======================================================================
195             sub if_sub {
196 1     1 1 3 my $self = shift;
197 1         2 my $contents = '';
198 1         1 my( $joken, $str, $stat, $cmd );
199              
200 1         11 $self->get_end();
201              
202 1 50       7 if( $self->{command} =~m/^\((.*?)\)(.*)/s ){
203 1         3 $joken = $1;
204 1         3 $str = $2;
205              
206 1         4 my @jokens = split( ' ', $joken );
207 1         4 for( my $i=0; $i
208 3         5 my $joken = $jokens[$i];
209 3 50       24 if( ($joken =~s/\$([\w\.-]+)\[(\d+)\]\.([\w\.-]+)\[(\d+)\]\.([\w\.-]+)/\$self->{params}->{$1}[$2]->{$3}[$4]->{$5}/g) ){
    50          
    50          
    100          
210             } elsif( ($joken =~s/\$([\w\.-]+)\[(\d+)\]\.([\w\.-]+)/\$self->{params}->{$1}[$2]->{$3}/g) ){
211             } elsif( ($joken =~s/\$([\w\.-]+)\.([\w\.-]+)/\$self->{params}->{$1}->{$2}/g) ){
212             } elsif( ($joken =~s/\$([\w\.-]+)/\$self->{params}->{$1}/g) ){
213             } else {
214             }
215 3         11 $jokens[$i] = $joken;
216             }
217 1         3 $joken = join( ' ', @jokens );
218             #print STDERR "joken=${joken}\n";
219              
220 1         1 $stat = 0;
221 1         3 $cmd = qq!\$stat = 1 if( $joken );!;
222 1         75 eval( $cmd ); ## no critic
223 1 50       4 if( $stat ){
224 1 50       3 if( $debug ){
225 0         0 $contents .= "". $str. "";
226             } else {
227 1         4 $contents .= $str;
228             }
229             } else {
230 0 0       0 if( $debug ){
231 0         0 $contents .= "". $self->{elsecommand}. "";
232             } else {
233 0         0 $contents .= $self->{elsecommand};
234             }
235             }
236             }
237              
238 1         5 $self->{contents} = $contents. $self->{contents};
239             }
240              
241             =head2 foreach_sub
242              
243             private function.
244              
245             =cut
246             #======================================================================
247             sub foreach_sub {
248 1     1 1 2 my $self = shift;
249 1         2 my( $contents, $cmd );
250              
251 1         1 $contents = '';
252              
253 1         3 $self->get_end();
254              
255 1 50       8 if( $self->{command} =~m/^\((.*?)\)(.*)$/s ){
256 1         3 my $joken = $1;
257 1         2 my $str = $2;
258 1         2 my( $param1, $param2, $param3 );
259 1 50       8 if( $joken =~m/^\s*\$(\w+?)\s+in\s+\$([\w\.\[\]]+?)\s*$/ ){
260 1         2 $param1 = $1;
261 1         2 $param2 = $2;
262             }
263 1         4 my @parts = split( /\./, $param2 );
264 1         2 my $cnt = scalar( @parts );
265 1         1 $param3 = $param2;
266 1         7 $param3 =~s/(\w+)/\{${1}\}/g;
267 1         2 $param3 =~s/\[\{(\d+)\}\]/\[${1}\]/g;
268 1         3 $param3 =~s/\./->/g;
269 1         2 $param3 = '$self->{params}->'. $param3;
270 1         2 my $stat = 0;
271 1         3 $cmd = qq!\$stat = 1 if( exists( $param3 ) );!;
272 1         68 eval( $cmd ); ## no critic
273 1 50       7 if( $@ ){
274 0         0 print STDERR "ERROR: $@: ${cmd}
\n";
275 0         0 $contents .= "ERROR: $@: ${cmd}";
276             }
277 1 50       3 if( $stat ){
278 1         1 my @datas;
279 1         3 $cmd = qq!\@datas = \@{${param3}};!;
280 1         60 eval( $cmd ); ## no critic
281 1         3 my $buff;
282 1         2 my $cnt = 0;
283 1         3 foreach my $item ( @datas ){
284 10         14 $buff = $str;
285 10         60 $buff =~s/\${$param1\./\${$param2\[$cnt\]\./g;
286 10         27 $buff =~s/\$$param1\./\$$param2\[$cnt\]\./g;
287 10         19 $contents .= $buff;
288 10         20 $cnt ++;
289             }
290             } else {
291 0         0 print STDERR "ERROR: foreach_sub: not exist ${param3}\n";
292 0         0 $contents .= "ERROR: foreach_sub: not exist ${param3}";
293             }
294             }
295              
296 1         5 $self->{contents} = $contents. $self->{contents};
297             }
298              
299             =head2 get_end
300              
301             private function.
302              
303             =cut
304             #======================================================================
305             sub get_end {
306 2     2 1 4 my $self = shift;
307 2         2 my( $htm, $tag, $retstr );
308 2         3 my $if = 0;
309 2         2 my $mode = 0;
310              
311 2         7 $self->{command} = '';
312 2         2 $self->{elsecommand} = '';
313              
314 2         6 while( $self->{contents} ne '' ){
315 3         22 ( $htm, $tag, $self->{contents} ) = split( /(#if|#foreach|#end|#else)/is, $self->{contents}, 2 );
316 3         5 $retstr .= $htm;
317 3 50 33     27 if(( $tag eq '#if' )||( $tag eq '#foreach' )){
    100          
    50          
318 0         0 $if += 1;
319             } elsif( $tag eq '#end' ){
320 2 50       5 if( $if == 0 ){
321 2         5 last;
322             }
323 0         0 $if -= 1;
324             } elsif( $tag eq '#else' ){
325 1 50       4 if( $if == 0 ){
326 1         1 $mode = 1;
327 1         2 $self->{command} = $retstr;
328 1         2 $retstr = '';
329 1         2 $tag = '';
330             }
331             }
332 1         4 $retstr .= $tag;
333             }
334              
335 2 100       6 if( $mode == 0 ){
336 1         2 $self->{command} = $retstr;
337             } else {
338 1         3 $self->{elsecommand} = $retstr;
339             }
340             }
341              
342             =head2 marge_val
343              
344             private function.
345              
346             =cut
347             #======================================================================
348             sub marge_val {
349 14     14 1 17 my $self = shift;
350 14         27 my $ch_name = shift;
351 14         14 my $retstr;
352 14         17 my $escape = 1;
353              
354 14         18 my $param = $ch_name;
355 14 100       55 if( $param =~s/\.escape\(\)$//g ){
    100          
356 1         2 $escape = 1;
357             } elsif( $param =~s/\.unescape\(\)$//g ){
358 1         1 $escape = 0;
359             }
360 14         110 $param =~s/(\w+)/\{${1}\}/g;
361 14         62 $param =~s/\[\{(\d+)\}\]/\[${1}\]/g;
362 14         34 $param =~s/\./->/g;
363 14         32 $param = '$self->{params}->'. $param;
364 14         28 my $cmd = qq!\$retstr = $param;!;
365 14         884 eval( $cmd ); ## no critic
366 14 100       55 if( $escape ){
367 13 50       29 if( defined( $retstr ) ){
368 13         24 $retstr =~s/&/&/g;
369 13         29 $retstr =~s/"/"/g;
370 13         19 $retstr =~s/'/'/g;
371 13         17 $retstr =~s/
372 13         25 $retstr =~s/>/>/g;
373             }
374             }
375             #print STDERR "\$ch_name=${ch_name}, \$param=${param}, \$escape=${escape}\n";
376              
377 14         71 $retstr;
378             }
379              
380             =head2 dump
381              
382             Dump parameters.
383              
384             =cut
385             #======================================================================
386             sub dump {
387 0     0 1   my $self = shift;
388              
389 2     2   2013 use Dumpvalue;
  2         9682  
  2         320  
390              
391 0           my $d = Dumpvalue->new();
392 0           print $d->dumpValue( \$self->{params} );
393 0 0         if( defined $self->{templateFile} ){
394 0           print "templateFile=". $self->{templateFile}. "\n";
395             }
396 0 0         if( defined $self->{templateData} ){
397 0           print "templateData=". $self->{templateData}. "\n";
398             }
399             }
400              
401              
402             =head1 AUTHOR
403              
404             Takuya Ichikawa, C<< >>
405              
406             =head1 BUGS
407              
408             Please report any bugs or feature requests to C, or through
409             the web interface at L. I will be notified, and then you'll
410             automatically be notified of progress on your bug as I make changes.
411              
412              
413              
414              
415             =head1 SUPPORT
416              
417             You can find documentation for this module with the perldoc command.
418              
419             perldoc TRD::Velocity
420              
421              
422             You can also look for information at:
423              
424             =over 4
425              
426             =item * RT: CPAN's request tracker
427              
428             L
429              
430             =item * AnnoCPAN: Annotated CPAN documentation
431              
432             L
433              
434             =item * CPAN Ratings
435              
436             L
437              
438             =item * Search CPAN
439              
440             L
441              
442             =back
443              
444              
445             =head1 ACKNOWLEDGEMENTS
446              
447              
448             =head1 COPYRIGHT & LICENSE
449              
450             Copyright 2010 Takuya Ichikawa, all rights reserved.
451              
452             This program is free software; you can redistribute it and/or modify it
453             under the same terms as Perl itself.
454              
455              
456             =cut
457              
458             1; # End of TRD::Velocity