File Coverage

blib/lib/Dotiac/DTL.pm
Criterion Covered Total %
statement 93 123 75.6
branch 24 54 44.4
condition 15 33 45.4
subroutine 8 10 80.0
pod 4 4 100.0
total 144 224 64.2


line stmt bran cond sub pod time code
1             ###############################################################################
2             #DTL.pm
3             #Last Change: 2008-01-19
4             #Copyright (c) 2006 Marc-Seabstian "Maluku" Lucksch
5             #Version 0.8
6             ####################
7             #This file is part of the Dotiac::DTL project.
8             #http://search.cpan.org/perldoc?Dotiac::DTL
9             #
10             #DTL.pm is published under the terms of the MIT license, which basically
11             #means "Do with it whatever you want". For more information, see the
12             #license.txt file that should be enclosed with libsofu distributions. A copy of
13             #the license is (at the time of writing) also available at
14             #http://www.opensource.org/licenses/mit-license.php .
15             ###############################################################################
16            
17            
18             package Dotiac::DTL;
19 11     11   333492 use base qw/Dotiac::DTL::Core/; #This is only used to make Test::Pod::Coverage, since most functions in the Dotiac::DTL namespace are documented in that file.
  11         26  
  11         7415  
20             require Dotiac::DTL::Tag;
21             require Digest::MD5;
22 11     11   59 use Carp qw/confess/;
  11         18  
  11         640  
23 11     11   52 use strict;
  11         51  
  11         270  
24 11     11   53 use warnings;
  11         17  
  11         291  
25 11     11   61 use Exporter;
  11         23  
  11         4117  
26             require File::Spec;
27             require File::Basename;
28            
29             our @EXPORT=();
30             our @EXPORT_OK=qw/Context Template/;
31             our $VERSION = 0.8;
32            
33            
34            
35             sub Template {
36 0     0 1 0 my $file=shift;
37 0 0       0 if (-e $file) {
    0          
    0          
38             }
39             elsif (-e "$file.html") {
40 0         0 $file="$file.html"
41             }
42             elsif (-e "$file.txt") {
43 0         0 $file="$file.txt" ;
44             }
45             else {
46 0         0 foreach my $dir (@Dotiac::DTL::TEMPLATE_DIRS) {
47 0 0 0     0 $file=File::Spec->catfile($dir,"$file.html") and last if -e File::Spec->catfile($dir,"$file.html");
48 0 0 0     0 $file=File::Spec->catfile($dir,"$file.txt") and last if -e File::Spec->catfile($dir,"$file.txt");
49 0 0 0     0 $file=File::Spec->catfile($dir,$file) and last if -e File::Spec->catfile($dir,$file);
50             }
51             }
52 0 0       0 return Dotiac::DTL->new($file,@_) if -e $file;
53 0         0 return Dotiac::DTL->new(\$file,@_);
54             }
55            
56            
57             sub Context {
58 0     0 1 0 return $_[0];
59             }
60            
61             my %cache;
62             sub newandcompile {
63 1     1 1 4 my $class=shift;
64 1         4 return $class->new(@_,1);
65             }
66            
67             {
68 11     11   58 no warnings "redefine";
  11         20  
  11         15011  
69             sub new {
70 294     294 1 312500 %Dotiac::DTL::params=();
71 294         612 my $class=shift;
72 294         498 my $data=shift;
73 294         582 my $t="";
74 294         649 my $filename="from cache";
75 294         436 my $changetime=0;
76 294         425 my $compile=shift; #1 compile, 0 no recompile, -1 skip compiled even if its there, undef=use compiled if there, recompile if needed.
77 294 100       1377 if (ref $data eq "SCALAR") {
    50          
78 1         2 $t=$$data;
79 1         2 $compile=0;
80 1         1 $filename="form SCALARref";
81 1         4 $Dotiac::DTL::currentdir=$Dotiac::DTL::CURRENTDIR;
82             }
83             elsif (not ref $data) {
84 293         505 $t=$data;
85 293         7816 my @f = File::Basename::fileparse($data);
86 293         622 $Dotiac::DTL::currentdir=$f[1];
87             #warn "Cached:",Data::Dumper->Dump([\%cache]);
88 293 50 66     7237 if (-e "$data.pm" and (($compile and $compile > 0) or not defined $compile)) {
      66        
89 133 50       1601 if (-e $data) {
90 133 100       2925 if ((stat("$data.pm"))[9] > (stat("$data"))[9]) {
91            
92             eval {
93 132 100       80606 $cache{"$data.pm"}={
94             template=>Dotiac::DTL::Compiled->new("Dotiac::DTL::Compiled::".require "$data.pm"),
95             currentdir=>$Dotiac::DTL::currentdir,
96             params=>{%Dotiac::DTL::params},
97             parser=>$Dotiac::DTL::PARSER,
98             changetime=>(stat("$data.pm"))[9]
99             } if not $cache{"$data.pm"};# or (exists $cache{"$data.pm"}->{changetime} and $cache{"$data.pm"}->{changetime} > -M "$data.pm");
100 132         586 $t="$data.pm";
101 132         216 $compile=0;
102 132         545 1;
103 132 50       558 } or do {
104 0         0 carp "Error while getting compiled template $data.pm:\n $@\n.";
105 0         0 undef $@;
106             };
107             }
108             else {
109 1         10 delete $cache{"$data.pm"};
110 1         4 delete $INC{"$data.pm"}; #Otherwise it won't work.
111 1 50 33     7 $compile=1 if $compile or not defined $compile;
112             }
113             }
114             else { # $data is not more here, but $data.pm is, use that one than.
115 0 0 0     0 if ($cache{"$data.pm"} and exists $cache{"$data.pm"}->{changetime} and $cache{"$data.pm"}->{changetime} < (stat("$data.pm"))[9]) {
      0        
116 0         0 carp "Foo";
117 0         0 delete $cache{"$data.pm"};
118 0         0 delete $INC{"$data.pm"};
119             }
120             eval {
121 0 0       0 $cache{"$data.pm"}={
122             template=>Dotiac::DTL->compiled("Dotiac::DTL::Compiled::".require "$data.pm"),
123             currentdir=>$Dotiac::DTL::currentdir,
124             params=>{%Dotiac::DTL::params},
125             parser=>$Dotiac::DTL::PARSER,
126             changetime=>(stat("$data.pm"))[9]
127             } if not $cache{"$data.pm"};# or (exists $cache{"$data.pm"}->{changetime} and $cache{"$data.pm"}->{changetime} > -M "$data.pm");
128 0         0 $t="$data.pm";
129 0         0 $compile=0;
130 0         0 1;
131 0 0       0 } or do {
132 0         0 croak "Error while getting compiled template $data.pm and $data is gone:\n $@\n.";
133 0         0 undef $@;
134             };
135             }
136             }
137 293 100 100     3391 if ($cache{$t} and $t eq $data and exists $cache{$t}->{changetime} and $cache{$t}->{changetime} < (stat("$t"))[9]) {
      66        
      100        
138 2         14 delete $cache{$t};
139             }
140 293 100       1144 unless ($cache{$t}) {
141 122 50       5055 open my $fh,"<",$data or croak "Can't open template $data: $!";
142 122         362 binmode $fh;
143 122         204 my $a=do {local $/,<$fh>};
  122         3060  
144 122         1633 close $fh;
145 122         419 $filename="\"$data\"";
146 122         1499 $changetime=(stat("$data"))[9];
147 122         738 $data=\$a;
148             }
149             }
150             else {
151 0         0 die "Can't work with $data!";
152             }
153 294 100       1084 unless ($cache{$t}) {
154 123 50       8199 eval "require $Dotiac::DTL::PARSER;" or croak "Can't load Parser '$Dotiac::DTL::PARSER': $@";
155 123         1423 my $parser=$Dotiac::DTL::PARSER->new();
156 123         1174 $cache{$t}={
157             template=>Dotiac::DTL::Tag->new("include/extend cycle detected"), #This prevents cycled includes to screw around during parsing time.
158             currentdir=>$Dotiac::DTL::currentdir,
159             params=>{%Dotiac::DTL::params},
160             parser=>$Dotiac::DTL::PARSER
161             };
162 123         269 my $pos=0;
163             eval {
164 123         721 $cache{$t}={
165             template=>$parser->parse($data,\$pos),
166             currentdir=>$Dotiac::DTL::currentdir,
167             params=>{%Dotiac::DTL::params},
168             parser=>$Dotiac::DTL::PARSER,
169             changetime=>$changetime
170             };
171 123         1032 1;
172 123 50       244 } or do {
173 0         0 croak "Error while getting template $filename:\n $@\n.";
174 0         0 undef $@;
175             };
176             }
177 294 100 66     1442 if ($compile and $compile > 0) {
178 128 50       136223 if (open my $cp,">","$t.pm") {
179             eval {
180 128         904 require Data::Dumper;
181 128         440 $Data::Dumper::Indent=2;
182 128         214 $Data::Dumper::Useqq=1;
183 128         395 my $template=$cache{$t}->{template};
184 128         994 my $digest=Digest::MD5::md5_hex($t);
185 128         1192 print $cp "#Autogenerated\n";
186 128         420 print $cp "package Dotiac::DTL::Compiled::$digest;\nuse strict;\nuse warnings;\nrequire Scalar::Util;\n#PARAMS USED:\nour ";
187            
188 128         1586 print $cp (Data::Dumper->Dump([$cache{$t}->{params}],["\$params"]));
189 128         14256 $template->perl($cp,0,$digest);
190 128         294 print $cp "\n#INIT\n";
191 128         720 $template->perlinit($cp,0,$digest);
192 128         279 print $cp "\nsub string {\n my \$vars=shift;\n my \$escape=shift;\n my \$r=\"\";\n";
193 128         660 $template->perlstring($cp,0,1,$digest);
194 128         272 print $cp " return \$r;\n}\n";
195 128         253 print $cp "sub print {\n my \$vars=shift;\n my \$escape=shift;\n";
196 128         550 $template->perlprint($cp,0,1,$digest);
197 128         294 print $cp "}\n";
198 128         250 print $cp "sub eval {\n my \$vars=shift;\n my \$escape=shift;\n";
199 128         643 $template->perleval($cp,0,1,$digest);
200 128         255 print $cp "}\n";
201 128         322 print $cp qq("$digest";);
202 128         9452 close $cp;
203 128         959 1;
204 128 50       338 } or do {
205 0         0 croak "Error while compiling template $filename:\n $@\n.";
206 0         0 undef $@;
207             };
208             }
209             else {
210 0         0 carp "Can't open output to $$data.pm while compiling: $!";
211             }
212             }
213 294         1298 Dotiac::DTL::Addon::restore();
214 294         3101 return "Dotiac::DTL::Template"->new($cache{$t}->{template},$cache{$t}->{currentdir},$cache{$t}->{parser},$cache{$t}->{params});
215             }
216             }
217             1;
218            
219             __END__