File Coverage

blib/lib/Dotiac/DTL/Addon/html_template_pure.pm
Criterion Covered Total %
statement 148 159 93.0
branch 74 88 84.0
condition 29 38 76.3
subroutine 9 10 90.0
pod 3 4 75.0
total 263 299 87.9


line stmt bran cond sub pod time code
1             ###############################################################################
2             #html_template_pure.pm
3             #Last Change: 2009-01-21
4             #Copyright (c) 2009 Marc-Seabstian "Maluku" Lucksch
5             #Version 0.4
6             ####################
7             #This file is an addon to the Dotiac::DTL project.
8             #http://search.cpan.org/perldoc?Dotiac::DTL
9             #
10             #html_template_pure.pm is published under the terms of the MIT license, which
11             #basically means "Do with it whatever you want". For more information, see the
12             #license.txt file that should be enclosed with the 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::Addon::html_template_pure;
19 11     11   987305 use strict;
  11         28  
  11         408  
20 11     11   64 use warnings;
  11         24  
  11         297  
21 11     11   5243 use Dotiac::DTL::Core;
  11         150681  
  11         382  
22 11     11   78 use base qw/Dotiac::DTL::Parser/;
  11         31  
  11         23069  
23             require Dotiac::DTL::Tag;
24             require Dotiac::DTL::Addon::html_template::Variable;
25             require Dotiac::DTL::Tag::autoescape;
26             require Dotiac::DTL::Tag::if;
27             require Dotiac::DTL::Tag::importloop;
28             require Dotiac::DTL::Tag::include;
29            
30             our $VERSION = 0.4;
31             our %OPTIONS=(
32             loop_context_vars=>1,
33             global_vars=>1,
34             default_escape=>""
35             );
36            
37             my @oldparser;
38            
39            
40            
41             sub import {
42 10     10   41894 push @oldparser,$Dotiac::DTL::PARSER;
43 10         20 $Dotiac::DTL::PARSER="Dotiac::DTL::Addon::html_template_pure";
44 10         25 $Dotiac::DTL::Addon::NOCOMPILE{'Dotiac::DTL::Addon::html_template_pure'}=1;
45 10         24 my $class=shift;
46 10         2539 while (my $a=shift @_) {
47 0         0 my $o=shift @_;
48 0 0 0     0 if (defined $o and exists $OPTIONS{$a}) {
49 0         0 $OPTIONS{$a}=$o;
50             }
51             }
52             }
53            
54             sub unimport {
55 8     8   4794 $Dotiac::DTL::PARSER=pop @oldparser;
56             }
57            
58             sub maketag {
59 239     239 0 318 my $self=shift;
60 239         298 my $tag=shift;
61 239         585 my $opts=shift;
62 239         272 my $pre=shift;
63 239         348 my @opts=();
64 239 50       1851 @opts=split /\s*((?:(?:[Dd][Ee][Ff][Aa][Uu][Ll][Tt])|(?:[Ee][Ss][Cc][Aa][Pp][Ee])|(?:[Nn][Aa][Mm][Ee]))\s*=)\s*/,$opts if $opts;
65 239         406 my %opts=();
66             #Convert options, quick and dirty
67 239         645 while (defined(my $o=shift(@opts))) {
68 415 100       965 next unless $o;
69 317 100       866 if (substr($o,-1,1) ne "=") {
70 141         155 push @{$opts{"name"}},$o;
  141         676  
71             }
72             else {
73 176         779 $o=~s/\s*=$//;
74 176         306 $o=lc $o;
75 176         178 push @{$opts{$o}},shift(@opts);
  176         833  
76             }
77            
78             }
79 239 100       638 if ($opts{default}) {
80 11         13 foreach my $value (@{$opts{default}}) {
  11         19  
81 11         18 my $f=substr $value,0,1;
82 11         13 my $e=substr $value,-1,1;
83 11 100 100     66 if ($f eq $e and $f eq '"' or $f eq "'") {
      100        
84 9         12 $value=substr $value,1,-1;
85             }
86 11         30 $value=Dotiac::DTL::escap($value);
87             }
88             }
89 239 100       660 if ($opts{name}) {
90 237         238 foreach my $value (@{$opts{name}}) {
  237         578  
91 237         880 $value=~s/["'\\\s}{]//g;
92             }
93             }
94 239 100       670 if ($opts{escape}) {
95 64         79 foreach my $value (@{$opts{escape}}) {
  64         130  
96 69         247 $value=~s/\W//g;
97 69         185 $value=~tr/A-Z/a-z/;
98             }
99             }
100 239         309 my $template=shift;
101 239         276 my $pos=shift;
102 239 100       627 if ($tag eq "var") {
    100          
    100          
    100          
    50          
103 182         193 my @filter;
104 182 100 100     875 push @{$opts{escape}},lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) if not ($opts{escape}) and $Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape} and lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) ne "html";
  8   100     26  
105 182 100       362 if ($opts{escape}) {
106 72         87 foreach my $v (@{$opts{escape}}) {
  72         134  
107 77 100       162 if ($v eq "js") {
108 22         44 push @filter,"escapejs";
109 22 100       144 push @filter,"safe" if lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) eq "html";
110             }
111 77 100       312 if ($v eq "html") {
112 21         48 push @filter,"escape";
113             }
114 77 100       144 if ($v eq "url") {
115 17         34 push @filter,"urlencode";
116 17 100       103 push @filter,"safe" if lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) eq "html";
117             }
118 77 100 66     670 if ($v eq "0" or $v eq "" or $v eq "off" or $v eq "none") {
      66        
      66        
119 17 100       77 push @filter,"safe" if lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) eq "html";
120             }
121             }
122             }
123 182 100       366 if ($opts{default}) {
124 11         11 push @filter,"default:".shift(@{$opts{default}});
  11         25  
125             }
126 182         246 my $name="``";
127 182 100       462 if ($opts{name}) {
128 180         174 $name=shift @{$opts{name}};
  180         331  
129             }
130 182         1100 return Dotiac::DTL::Addon::html_template::Variable->new($pre,$name,\@filter);
131             }
132             elsif ($tag eq "if") {
133 26         43 my $found="";
134 26         34 my $name="``";
135 26 50       72 if ($opts{name}) {
136 26         36 $name=shift @{$opts{name}};
  26         51  
137             }
138 26         116 my $true=$self->parse($template,$pos,\$found,"else","endif");
139 26 100       548 if ($found eq "else") {
140 8         152 return bless {'cond'=>[$name],true=>$true,false=>$self->parse($template,$pos,\$found,"endif"),p=>$pre},"Dotiac::DTL::Tag::if";
141             }
142 18         187 return bless {'cond'=>[$name],true=>$true,p=>$pre},"Dotiac::DTL::Tag::if";
143             }
144             elsif ($tag eq "unless") {
145 11         15 my $found="";
146 11         15 my $name="``";
147 11 50       28 if ($opts{name}) {
148 11         13 $name=shift @{$opts{name}};
  11         22  
149             }
150 11         43 my $true=$self->parse($template,$pos,\$found,"else","endif");
151 11 100       118 if ($found eq "else") {
152 6         31 return bless {'not'=>[$name],true=>$true,false=>$self->parse($template,$pos,\$found,"endif"),p=>$pre},"Dotiac::DTL::Tag::if";
153             }
154 5         44 return bless {'not'=>[$name],true=>$true,p=>$pre},"Dotiac::DTL::Tag::if";
155             }
156             elsif ($tag eq "loop") {
157 18         35 my $found="";
158 18         31 my $name="``";
159 18 50       65 if ($opts{name}) {
160 18         24 $name=shift @{$opts{name}};
  18         59  
161             }
162 18         99 my $content=$self->parse($template,$pos,\$found,"endimportloop","empty");
163 18 100       92 if ($found eq "empty") {
164 1         5 return bless {source=>$name,content=>$content,p=>$pre,empty=>$self->parse($template,$pos,\$found,"endimportloop"),merge=>$Dotiac::DTL::Addon::html_template_pure::OPTIONS{global_vars},contextvars=>$Dotiac::DTL::Addon::html_template_pure::OPTIONS{loop_context_vars}},"Dotiac::DTL::Tag::importloop";
165             }
166 17         196 return bless {source=>$name,content=>$content,p=>$pre,merge=>$Dotiac::DTL::Addon::html_template_pure::OPTIONS{global_vars},contextvars=>$Dotiac::DTL::Addon::html_template_pure::OPTIONS{loop_context_vars}},"Dotiac::DTL::Tag::importloop";
167             }
168             elsif ($tag eq "include") {
169 2         5 my $name;
170 2 50       10 if ($opts{name}) {
171 2         46 $name=shift @{$opts{name}};
  2         45  
172             }
173 2 50       22 return Dotiac::DTL::Addon::html_template::Variable->new($pre,"``",[]) unless $name;
174 2   33     4 return eval {
175             my $tem = Dotiac::DTL->safenew($name);
176             return bless {content=>$tem->{first},load=>$name,p=>$pre},"Dotiac::DTL::Tag::include";
177             } || Dotiac::DTL::Addon::html_template::Variable->new($pre,"``",[]);
178             }
179 0         0 return undef;
180            
181             }
182            
183            
184             sub new {
185 53     53 1 342745 my $class=shift;
186 53         109 my $self={};
187 53         138 bless $self,$class;
188 53         149 return $self;
189             }
190            
191            
192             sub parse {
193 233     233 1 1394 my $self=shift;
194 233         272 my $template=shift;
195 233         245 my $pos=shift;
196 233         272 my $start=$$pos;
197 233         452 my @end = @_;
198 233         259 my $found;
199 233 100       615 $found=shift @end if @end;
200 233         273 local $_;
201 233         504 while ($Dotiac::DTL::PARSER eq __PACKAGE__) {
202 233         512 pos($$template) = $$pos;
203 233 100       2049 if($$template=~m/\G(.*?)<(?:!--\s*)?
204             ([\/]?)\s*
205             [Tt][Mm][Pp][Ll]_((?:[Vv][Aa][Rr])|(?:[Ii][Ff])|(?:[Ee][Ll][Ss][Ee])|(?:[Uu][Nn][Ll][Ee][Ss][Ss])|(?:[Ll][Oo][Oo][Pp])|(?:[Ii][Nn][Cc][Ll][Uu][Dd][Ee]))
206             \s*(
207             (?:
208             (?:
209             (?:(?:[Dd][Ee][Ff][Aa][Uu][Ll][Tt])|(?:[Ee][Ss][Cc][Aa][Pp][Ee])|(?:[Nn][Aa][Mm][Ee]))
210             \s*=\s*
211             )?
212             (?!-->)(?:(?:"[^">]*")|(?:'[^'>]*')|(?:[^\s=>]*))\s*
213             )*
214             )
215             (?:--)?>/sgx) {
216 212         425 my $pre=$1;
217 212         449 my $end=$2;
218 212         363 my $tag=lc($3);
219 212         306 my $content=$4;
220 212         335 $$pos=pos($$template);
221             #warn "Pre:$pre\nTag:$tag,End:$end\nContent=$content\nStart=$start, end=$$pos" if $tag eq "if";
222 212         361 my $tagname=$tag;
223 212 100       500 $tagname="end$tag" if $end;
224 212 100 100     600 $tagname="endimportloop" if $end and $tag eq "loop";
225 212 100 100     484 $tagname="endif" if $end and $tag eq "unless";
226 212 100 50     485 $$found = $tagname and return Dotiac::DTL::Tag->new($pre) if $found and grep {$_ eq $tagname} @end;
  148   100     601  
227 170         445 my $t=$self->maketag($tag,$content,$pre,$template,$pos);
228 170 50       513 if ($t) {
229 170 100       322 if ($$pos >= length $$template) {
230 32         96 $t->next(Dotiac::DTL::Tag->new(""));
231             }
232             else {
233 138         403 $t->next($self->parse($template,$pos,@_));
234             }
235 170 100       632 unless ($start) {
236 50 100       1655 return $t if lc($Dotiac::DTL::Addon::html_template_pure::OPTIONS{default_escape}) eq "html";
237 45         186 return bless {p=>"",n=>Dotiac::DTL::Tag->new(""),escape=>0,content=>$t},"Dotiac::DTL::Tag::autoescape"; #Autoescape off unless default_escape == html
238             }
239 120         485 return $t;
240             }
241             else {
242 0         0 warn "Couldn't make anything with $tag,$tagname, maybe your template is unbalanced";
243             }
244             }
245             else {
246 21         36 $$pos=length $$template;
247 21         100 return Dotiac::DTL::Tag->new(substr $$template,$start);
248             }
249            
250             }
251 0           my $parser=$Dotiac::DTL::PARSER->new();
252 0           my @args=($template,$pos);
253 0 0         push @args,$found if $found;
254 0 0         push @args,@end if @end;
255 0           return $parser->parse(@args);
256             }
257            
258             sub unparsed { #This isn't needed here.
259 0     0 1   return "";
260             }
261            
262             1;
263             __END__