File Coverage

blib/lib/Template/Alloy/HTE.pm
Criterion Covered Total %
statement 234 301 77.7
branch 165 242 68.1
condition 60 123 48.7
subroutine 6 14 42.8
pod 10 11 90.9
total 475 691 68.7


line stmt bran cond sub pod time code
1             package Template::Alloy::HTE;
2              
3             =head1 NAME
4              
5             Template::Alloy::HTE - HTML::Template and HTML::Template::Expr roles.
6              
7             =cut
8              
9 3     3   18 use strict;
  3         7  
  3         139  
10 3     3   19 use warnings;
  3         8  
  3         127  
11 3     3   20 use Template::Alloy;
  3         8  
  3         26  
12              
13             our $VERSION = $Template::Alloy::VERSION;
14              
15 0     0 0 0 sub new { die "This class is a role for use by packages such as Template::Alloy" }
16              
17             ###----------------------------------------------------------------###
18             ### support for few HTML::Template and HTML::Template::Expr calling syntax
19              
20             sub register_function {
21 0     0 1 0 my ($name, $sub) = @_;
22 0         0 $Template::Alloy::SCALAR_OPS->{$name} = $sub;
23             }
24              
25 0     0 1 0 sub clear_param { shift->{'_vars'} = {} }
26              
27 0     0 1 0 sub query { shift->throw('query', "Not implemented in Template::Alloy") }
28              
29 0     0 1 0 sub new_file { my $class = shift; my $in = shift; $class->new(source => $in, type => 'filename', @_) }
  0         0  
  0         0  
30 0     0 1 0 sub new_scalar_ref { my $class = shift; my $in = shift; $class->new(source => $in, type => 'scalarref', @_) }
  0         0  
  0         0  
31 0     0 1 0 sub new_array_ref { my $class = shift; my $in = shift; $class->new(source => $in, type => 'arrayref', @_) }
  0         0  
  0         0  
32 0     0 1 0 sub new_filehandle { my $class = shift; my $in = shift; $class->new(source => $in, type => 'filehandle', @_) }
  0         0  
  0         0  
33              
34             ###----------------------------------------------------------------###
35              
36             sub parse_tree_hte {
37 297     297 1 385 my $self = shift;
38 297         355 my $str_ref = shift;
39 297 50 33     1171 if (! $str_ref || ! defined $$str_ref) {
40 0         0 $self->throw('parse.no_string', "No string or undefined during parse", undef, 1);
41             }
42              
43 297   50     1430 local $self->{'V2EQUALS'} = $self->{'V2EQUALS'} || 0;
44 297   66     1476 local $self->{'NO_TT'} = $self->{'NO_TT'} || ($self->{'SYNTAX'} eq 'hte' ? 0 : 1);
45              
46 297         1418 local $self->{'START_TAG'} = qr{<(|!--\s*)(/?)([+=~-]?)[Tt][Mm][Pp][Ll]_(\w+)\b};
47 297 100       1044 local $self->{'_start_tag'} = (! $self->{'INTERPOLATE'}) ? $self->{'START_TAG'} : qr{(?: $self->{'START_TAG'} | (\$))}sx;
48 297         542 local $self->{'_end_tag'}; # changes over time
49              
50 297         372 my $dirs = $Template::Alloy::Parse::DIRECTIVES;
51 297         368 my $aliases = $Template::Alloy::Parse::ALIASES;
52 297         634 local @{ $dirs }{ keys %$aliases } = values %$aliases; # temporarily add to the table
  297         972  
53 297         632 local @{ $self }{@Template::Alloy::CONFIG_COMPILETIME} = @{ $self }{@Template::Alloy::CONFIG_COMPILETIME};
  297         4298  
  297         1566  
54 297 50       1465 delete $dirs->{'JS'} if ! $self->{'COMPILE_JS'};
55              
56 297         810 my @tree; # the parsed tree
57 297         475 my $pointer = \@tree; # pointer to current tree to handle nested blocks
58 297         357 my @state; # maintain block levels
59 297         587 local $self->{'_state'} = \@state; # allow for items to introspect (usually BLOCKS)
60 297         698 local $self->{'_no_interp'} = 0; # no interpolation in perl
61 297         332 my @in_view; # let us know if we are in a view
62             my @blocks; # storage for defined blocks
63 0         0 my @meta; # place to store any found meta information (to go into META)
64 297         745 my $post_chomp = 0; # previous post_chomp setting
65 297         317 my $continue = 0; # flag for multiple directives in the same tag
66 297         281 my $post_op = 0; # found a post-operative DIRECTIVE
67 297         333 my $capture; # flag to start capture
68             my $func;
69 0         0 my $pre_chomp;
70 0         0 my $node;
71 0         0 my ($comment, $is_close);
72 297         836 pos($$str_ref) = 0;
73 297   66     1329 my $allow_expr = ! defined($self->{'EXPR'}) || $self->{'EXPR'}; # default is on
74              
75 297         367 while (1) {
76             ### allow for TMPL_SET foo = PROCESS foo
77 738 100       1276 if ($capture) {
78 4 50       23 $func = $$str_ref =~ m{ \G \s* (\w+)\b }gcx
79             ? uc $1 : $self->throw('parse', "Error looking for block in capture DIRECTIVE", undef, pos($$str_ref));
80 4 50       35 $func = $aliases->{$func} if $aliases->{$func};
81 4 50 33     25 if ($func ne 'VAR' && ! $dirs->{$func}) {
82 0         0 $self->throw('parse', "Found unknown DIRECTIVE ($func)", undef, pos($$str_ref) - length($func));
83             }
84              
85 4         13 $node = [$func, pos($$str_ref) - length($func), undef];
86              
87 4         7 push @{ $capture->[4] }, $node;
  4         10  
88 4         6 undef $capture;
89              
90             ### handle all other TMPL tags
91             } else {
92             ### find the next opening tag
93 734 100       5522 $$str_ref =~ m{ \G (.*?) $self->{'_start_tag'} }gcxs
94             || last;
95 461         1566 my ($text, $dollar) = ($1, $6);
96 461 100       1929 ($comment, $is_close, $pre_chomp, $func) = ($2, $3, $4, uc $5) if ! $dollar;
97              
98             ### found a text portion - chomp it and store it
99 461 100       1005 if (length $text) {
100 190 50       354 if (! $post_chomp) { }
    0          
    0          
    0          
101 0         0 elsif ($post_chomp == 1) { $text =~ s{ ^ [^\S\n]* \n }{}x }
102 0         0 elsif ($post_chomp == 2) { $text =~ s{ ^ \s+ }{ }x }
103 0         0 elsif ($post_chomp == 3) { $text =~ s{ ^ \s+ }{}x }
104 190 50       546 push @$pointer, $text if length $text;
105             }
106              
107             ### handle variable interpolation ($2 eq $)
108 461 100       826 if ($dollar) {
109             ### inspect previous text chunk for escape slashes
110 32 50       83 my $n = ($text =~ m{ (\\+) $ }x) ? length($1) : 0;
111 32 50 33     73 if ($n && ! $self->{'_no_interp'}) {
112 0         0 my $chop = int(($n + 1) / 2); # were there odd escapes
113 0 0 0     0 substr($pointer->[-1], -$chop, $chop, '') if defined($pointer->[-1]) && ! ref($pointer->[-1]);
114             }
115 32 50 33     167 if ($self->{'_no_interp'} || $n % 2) {
116 0         0 push @$pointer, $dollar;
117 0         0 next;
118             }
119              
120 32         79 my $not = $$str_ref =~ m{ \G ! }gcx;
121 32         42 my $mark = pos($$str_ref);
122 32         37 my $ref;
123 32 100       71 if ($$str_ref =~ m{ \G \{ }gcx) {
124 12         33 local $self->{'_operator_precedence'} = 0; # allow operators
125 12         51 local $self->{'_end_tag'} = qr{\}};
126 12         41 $ref = $self->parse_expr($str_ref);
127 12 50       99 $$str_ref =~ m{ \G \s* $Template::Alloy::Parse::QR_COMMENTS \} }gcxo
128             || $self->throw('parse', 'Missing close }', undef, pos($$str_ref));
129             } else {
130 20         46 local $self->{'_operator_precedence'} = 1; # no operators
131 20         63 local $Template::Alloy::Parse::QR_COMMENTS = qr{};
132 20         66 $ref = $self->parse_expr($str_ref);
133             }
134 32 50       71 $self->throw('parse', "Error while parsing for interpolated string", undef, pos($$str_ref))
135             if ! defined $ref;
136 32 100 100     125 if (! $not && $self->{'SHOW_UNDEFINED_INTERP'}) {
137 8         41 $ref = [[undef, '//', $ref, '$'.substr($$str_ref, $mark, pos($$str_ref)-$mark)], 0];
138             }
139 32         93 push @$pointer, ['GET', $mark, pos($$str_ref), $ref];
140 32         39 $post_chomp = 0; # no chomping after dollar vars
141 32         68 next;
142             }
143              
144             ### make sure we know this directive
145 429 50       917 $func = $aliases->{$func} if $aliases->{$func};
146 429 50 66     1751 if ($func ne 'VAR' && ! $dirs->{$func}) {
147 0         0 $self->throw('parse', "Found unknow DIRECTIVE ($func)", undef, pos($$str_ref) - length($func));
148             }
149 429         1423 $node = [$func, pos($$str_ref) - length($func) - length($pre_chomp) - 5, undef];
150              
151             ### take care of chomping - yes HT now get CHOMP SUPPORT
152 429   66     1695 $pre_chomp ||= $self->{'PRE_CHOMP'};
153 429 100       842 $pre_chomp =~ y/-=~+/1230/ if $pre_chomp;
154 429 50 66     950 if ($pre_chomp && $pointer->[-1] && ! ref $pointer->[-1]) {
      66        
155 2 50       6 if ($pre_chomp == 1) { $pointer->[-1] =~ s{ (?:\n|^) [^\S\n]* \z }{}x }
  2 0       12  
    0          
156 0         0 elsif ($pre_chomp == 2) { $pointer->[-1] =~ s{ (\s+) \z }{ }x }
157 0         0 elsif ($pre_chomp == 3) { $pointer->[-1] =~ s{ (\s+) \z }{}x }
158 2 50       9 splice(@$pointer, -1, 1, ()) if ! length $pointer->[-1]; # remove the node if it is zero length
159             }
160              
161 429         708 push @$pointer, $node;
162 429 100       2124 $self->{'_end_tag'} = $comment ? qr{([+=~-]?)-->} : qr{([+=~-]?)>}; # how will this tag end
163             }
164              
165 433         1181 $$str_ref =~ m{ \G \s+ }gcx;
166              
167             ### parse remaining tag details
168 433 100       833 if (! $is_close) {
169             ### handle HT style nodes
170 361 100       1403 if ($func =~ /^(IF|ELSIF|ELSE|UNLESS|LOOP|VAR|INCLUDE)$/) {
171 307 100       851 $func = $node->[0] = 'GET' if $func eq 'VAR';
172              
173             ### handle EXPR attribute
174 307 100       1064 if ($func eq 'ELSE') {
    100          
175             # do nothing
176             } elsif ($$str_ref =~ m{ \G [Ee][Xx][Pp][Rr] \s*=\s* ([\"\']?) \s* }gcx) {
177 61 100       143 if (! $allow_expr) {
178 6         37 $self->throw('parse', 'EXPR are not allowed without hte mode', undef, pos($$str_ref));
179             }
180 55         113 my $quote = $1;
181 55 100       657 local $self->{'_end_tag'} = $quote ? qr{$quote\s*$self->{'_end_tag'}} : $self->{'_end_tag'};
182 55         96 $node->[3] = eval { $self->parse_expr($str_ref) };
  55         287  
183 55 100       164 if (! defined($node->[3])) {
184 2   33     56 my $err = $@ || $self->exception('parse', 'Error while looking for EXPR', undef, pos($$str_ref));
185 2 50 33     27 $err->info($err->info . " (Could be a missing close quote near expr=$quote)") if $quote && UNIVERSAL::can($err, 'info');
186 2         8 $self->throw($err);
187             }
188 53 100       125 if ($quote) {
189 45 50       796 $$str_ref =~ m{ \G $quote }gcx
190             || $self->throw('parse', "Missing close quote ($quote)", undef, pos($$str_ref));
191             }
192 53 100       228 if ($func eq 'INCLUDE') {
    100          
193 6         11 $node->[0] = 'PROCESS'; # no need to localize the stash
194 6         25 $node->[3] = [[[undef, '{}'],0], $node->[3]];
195             } elsif ($func eq 'UNLESS') {
196 4         9 $node->[0] = 'IF';
197 4         15 $node->[3] = [[undef, '!', $node->[3]], 0];
198             }
199 53 100       234 if ($self->{'AUTO_FILTER'}) {
200 4 50       14 $node->[3] = [[undef, '~', $node->[3]], 0] if ! ref $node->[3];
201 4 100 66     7 push @{ $node->[3] }, '|', $self->{'AUTO_FILTER'}, 0 if @{ $node->[3] } < 3 || $node->[3]->[-3] ne '|';
  2         8  
  4         27  
202             }
203              
204             ### handle "normal" NAME attributes
205             } else {
206              
207 220         249 my ($name, $escape, $default);
208 220         393 while (1) {
209 474 100       2073 if ($$str_ref =~ m{ \G (\w+) \s*=\s* }gcx) {
    100          
    100          
210 112         251 my $key = lc $1;
211 112 50       581 my $val = $$str_ref =~ m{ \G ([\"\']) (.*?) (?
    100          
212             : $$str_ref =~ m{ \G ([\w./+_]+) \s* }gcx ? $1
213             : $self->throw('parse', "Error while looking for value of \"$key\" attribute", undef, pos($$str_ref));
214 112 100       236 if ($key eq 'name') {
215 54   33     208 $name ||= $val;
216             } else {
217 58 100       178 $self->throw('parse', uc($key)." not allowed in TMPL_$func tag", undef, pos($$str_ref)) if $func ne 'GET';
218 50 100 100     97 if ($key eq 'escape') { $escape ||= lc $val }
  30 100       120  
219 16   66     64 elsif ($key eq 'default') { $default ||= $val }
220 4         33 else { $self->throw('parse', uc($key)." not allowed in TMPL_$func tag", undef, pos($$str_ref)) }
221             }
222             } elsif ($$str_ref =~ m{ \G ([\w./+_]+) \s* }gcx) {
223 142   66     563 $name ||= $1;
224             } elsif ($$str_ref =~ m{ \G ([\"\']) (.*?) (?
225 12   33     60 $name ||= $2;
226             } else {
227 208         290 last;
228             }
229             }
230              
231 208 50 33     780 $self->throw('parse', 'Error while looking for NAME', undef, pos($$str_ref)) if ! defined($name) || ! length($name);
232 208 100       540 if ($func eq 'INCLUDE') {
    100          
233 20         33 $node->[0] = 'PROCESS'; # no need to localize the stash
234 20         105 $node->[3] = [[[undef, '{}'],0], $name];
235             } elsif ($func eq 'UNLESS') {
236 6         18 $node->[0] = 'IF';
237 6         29 $node->[3] = [[undef, '!', [$name, 0]], 0];
238             } else {
239 182         612 $node->[3] = [$name, 0]; # set the variable
240             }
241 208 100       472 $node->[3] = [[undef, '||', $node->[3], $default], 0] if $default;
242              
243             ### dress up node before finishing
244 208 100 100     966 $escape = lc $self->{'DEFAULT_ESCAPE'} if ! $escape && $self->{'DEFAULT_ESCAPE'};
245 208 100       662 if ($escape) {
    100          
246 26 50       58 $self->throw('parse', "ESCAPE not allowed in TMPL_$func tag", undef, pos($$str_ref)) if $func ne 'GET';
247 26 100 100     94 if ($escape eq 'html' || $escape eq '1') {
    100          
    100          
248 20         21 push @{ $node->[3] }, '|', 'html', 0;
  20         60  
249             } elsif ($escape eq 'url') {
250 2         4 push @{ $node->[3] }, '|', 'url', 0;
  2         9  
251             } elsif ($escape eq 'js') {
252 2         5 push @{ $node->[3] }, '|', 'js', 0;
  2         6  
253             }
254             } elsif ($self->{'AUTO_FILTER'}) {
255 2         4 push @{ $node->[3] }, '|', $self->{'AUTO_FILTER'}, 0;
  2         7  
256             }
257             }
258 287         579 $node->[2] = pos $$str_ref;
259              
260              
261             ### handle TT Directive extensions
262             } else {
263 54 100       417 $self->throw('parse', "Found a TT tag $func with NO_TT enabled", undef, pos($$str_ref)) if $self->{'NO_TT'};
264 50         67 $node->[3] = eval { $dirs->{$func}->[0]->($self, $str_ref, $node) };
  50         208  
265 50 50       133 if (my $err = $@) {
266 0 0 0     0 $err->node($node) if UNIVERSAL::can($err, 'node') && ! $err->node;
267 0         0 die $err;
268             }
269 50         95 $node->[2] = pos $$str_ref;
270             }
271             }
272              
273             ### handle ending tags - or continuation blocks
274 409 100 100     2547 if ($is_close || $dirs->{$func}->[4]) {
    100          
    100          
275 100 50       230 if (! @state) {
276 0         0 $self->throw('parse', "Found an $func tag while not in a block", $node, pos($$str_ref));
277             }
278 100         152 my $parent_node = pop @state;
279              
280             ### TODO - check for matching loop close name
281 100 100       255 $func = $node->[0] = 'END' if $is_close;
282              
283             ### handle continuation blocks such as elsif, else, catch etc
284 100 100       264 if ($dirs->{$func}->[4]) {
285 28         36 pop @$pointer; # we will store the node in the parent instead
286 28         53 $parent_node->[5] = $node;
287 28         43 my $parent_type = $parent_node->[0];
288 28 50       95 if (! $dirs->{$func}->[4]->{$parent_type}) {
289 0         0 $self->throw('parse', "Found unmatched nested block", $node, pos($$str_ref));
290             }
291             }
292              
293             ### restore the pointer up one level (because we hit the end of a block)
294 100 50       212 $pointer = (! @state) ? \@tree : $state[-1]->[4];
295              
296             ### normal end block
297 100 100       251 if (! $dirs->{$func}->[4]) {
298 72 100       323 if ($parent_node->[0] eq 'BLOCK') { # move BLOCKS to front
    50          
    50          
299 6 50 33     34 if (defined($parent_node->[3]) && @in_view) {
300 0         0 push @{ $in_view[-1] }, $parent_node;
  0         0  
301             } else {
302 6         10 push @blocks, $parent_node;
303             }
304 6 100 66     34 if ($pointer->[-1] && ! $pointer->[-1]->[6]) { # capturing doesn't remove the var
305 4         11 splice(@$pointer, -1, 1, ());
306             }
307             } elsif ($parent_node->[0] eq 'VIEW') {
308 0         0 my $ref = { map {($_->[3] => $_->[4])} @{ pop @in_view }};
  0         0  
  0         0  
309 0         0 unshift @{ $parent_node->[3] }, $ref;
  0         0  
310             } elsif ($dirs->{$parent_node->[0]}->[5]) { # allow no_interp to turn on and off
311 0         0 $self->{'_no_interp'}--;
312             }
313              
314              
315             ### continuation block - such as an elsif
316             } else {
317 28         34 push @state, $node;
318 28   50     137 $pointer = $node->[4] ||= [];
319             }
320 100         196 $node->[2] = pos $$str_ref;
321              
322             ### handle block directives
323             } elsif ($dirs->{$func}->[2]) {
324 72         122 push @state, $node;
325 72   50     327 $pointer = $node->[4] ||= []; # allow future parsed nodes before END tag to end up in current node
326 72 50       156 push @in_view, [] if $func eq 'VIEW';
327 72 50       216 $self->{'_no_interp'}++ if $dirs->{$node->[0]}->[5] # allow no_interp to turn on and off
328              
329             } elsif ($func eq 'META') {
330 2         3 unshift @meta, @{ $node->[3] }; # first defined win
  2         7  
331 2         3 $node->[3] = undef; # only let these be defined once - at the front of the tree
332             }
333              
334              
335             ### look for the closing tag
336 409 100       3028 if ($$str_ref =~ m{ \G \s* $self->{'_end_tag'} }gcxs) {
    50          
337 405   66     1913 $post_chomp = $1 || $self->{'POST_CHOMP'};
338 405 100       835 $post_chomp =~ y/-=~+/1230/ if $post_chomp;
339 405         448 $continue = 0;
340 405         408 $post_op = 0;
341 405         656 next;
342              
343             ### setup capturing
344             } elsif ($node->[6]) {
345 4         7 $capture = $node;
346 4         6 next;
347              
348             ### no closing tag
349             } else {
350 0         0 $self->throw('parse', "Not sure how to handle tag", $node, pos($$str_ref));
351             }
352             }
353              
354             ### cleanup the tree
355 273 100       610 unshift(@tree, @blocks) if @blocks;
356 273 100       563 unshift(@tree, ['META', 1, 1, \@meta]) if @meta;
357 273 50       727 $self->throw('parse', "Missing 0;
358              
359             ### pull off the last text portion - if any
360 273 100       780 if (pos($$str_ref) != length($$str_ref)) {
361 82         198 my $text = substr $$str_ref, pos($$str_ref);
362 82 100       187 if (! $post_chomp) { }
    50          
    0          
    0          
363 2         9 elsif ($post_chomp == 1) { $text =~ s{ ^ [^\S\n]* \n }{}x }
364 0         0 elsif ($post_chomp == 2) { $text =~ s{ ^ \s+ }{ }x }
365 0         0 elsif ($post_chomp == 3) { $text =~ s{ ^ \s+ }{}x }
366 82 100       269 push @$pointer, $text if length $text;
367             }
368              
369 273         4235 return \@tree;
370             }
371              
372             ###----------------------------------------------------------------###
373             ### a few HTML::Template and HTML::Template::Expr routines
374              
375             sub param {
376 248     248 1 2315 my $self = shift;
377 248         321 my $args;
378 248 50       658 if (@_ == 1) {
379 248         343 my $key = shift;
380 248 50       720 if (ref($key) ne 'HASH') {
381 0 0       0 $key = lc $key if ! $self->{'CASE_SENSITIVE'};
382 0         0 return $self->{'_vars'}->{$key};
383             }
384 248         859 $args = [%$key];
385             } else {
386 0 0       0 $self->throw('param', "Odd number of parameters") if @_ % 2;
387 0         0 $args = \@_;
388             }
389 248         730 while (@$args) {
390 198         376 my $key = shift @$args;
391 198 50       707 $key = lc $key if ! $self->{'CASE_SENSITIVE'};
392 198         858 $self->{'_vars'}->{$key} = shift @$args;
393             }
394 248         579 return;
395             }
396              
397             sub output {
398 248     248 1 896 my $self = shift;
399 248 50       725 my $args = ref($_[0]) eq 'HASH' ? shift : {@_};
400 248   50     1339 my $type = $self->{'TYPE'} || '';
401              
402 248         277 my $content;
403 248 50 33     3745 if ($type eq 'filehandle' || $self->{'FILEHANDLE'}) {
    50 33        
    50 33        
    50 33        
404 0   0     0 my $in = $self->{'FILEHANDLE'} || $self->{'SOURCE'} || $self->throw('output', 'Missing source for type filehandle');
405 0         0 local $/ = undef;
406 0         0 $content = <$in>;
407 0         0 $content = \$content;
408             } elsif ($type eq 'arrayref' || $self->{'ARRAYREF'}) {
409 0   0     0 my $in = $self->{'ARRAYREF'} || $self->{'SOURCE'} || $self->throw('output', 'Missing source for type arrayref');
410 0         0 $content = join "", @$in;
411 0         0 $content = \$content;
412             } elsif ($type eq 'filename' || $self->{'FILENAME'}) {
413 0   0     0 $content = $self->{'FILENAME'} || $self->{'SOURCE'} || $self->throw('output', 'Missing source for type filename');
414             } elsif ($type eq 'scalarref' || $self->{'SCALARREF'}) {
415 248   33     802 $content = $self->{'SCALARREF'} || $self->{'SOURCE'} || $self->throw('output', 'Missing source for type scalarref');
416             } else {
417 0         0 $self->throw('output', "Unknown input type");
418             }
419              
420              
421 248   100     766 my $param = $self->{'_vars'} || {};
422 248 50       698 if (my $ref = $self->{'ASSOCIATE'}) {
423 0 0       0 foreach my $obj (ref($ref) eq 'ARRAY' ? @$ref : $ref) {
424 0         0 foreach my $key ($obj->param) {
425 0 0       0 $self->{'_vars'}->{$self->{'CASE_SENSITIVE'} ? $key : lc($key)} = $obj->param($key);
426             }
427             }
428             }
429              
430              
431             ### override some TT defaults
432 248 50       758 local $self->{'FILE_CACHE'} = $self->{'DOUBLE_FILE_CACHE'} ? 1 : $self->{'FILE_CACHE'};
433 248 50       651 my $cache_size = ($self->{'CACHE'}) ? undef : 0;
434 248 50 0     518 my $compile_dir = (! $self->{'FILE_CACHE'}) ? undef : $self->{'FILE_CACHE_DIR'} || $self->throw('output', 'Missing file_cache_dir');
435 248 50       521 my $stat_ttl = (! $self->{'BLIND_CACHE'}) ? undef : 60; # not sure how high to set the blind cache
436 248 50       549 $cache_size = undef if $self->{'DOUBLE_FILE_CACHE'};
437              
438 248   100     1178 local $self->{'SYNTAX'} = $self->{'SYNTAX'} || 'hte';
439 248         654 local $self->{'GLOBAL_CACHE'} = $self->{'CACHE'};
440 248 50       836 local $self->{'ADD_LOCAL_PATH'} = defined($self->{'ADD_LOCAL_PATH'}) ? $self->{'ADD_LOCAL_PATH'} : 1;
441 248         510 local $self->{'CACHE_SIZE'} = $cache_size;
442 248         463 local $self->{'STAT_TTL'} = $stat_ttl;
443 248         390 local $self->{'COMPILE_DIR'} = $compile_dir;
444 248         408 local $self->{'ABSOLUTE'} = 1;
445 248         394 local $self->{'RELATIVE'} = 1;
446 248         522 local $self->{'INCLUDE_PATH'} = $self->{'PATH'};
447 248         848 local $self->{'LOWER_CASE_VAR_FALLBACK'} = ! $self->{'CASE_SENSITIVE'}; # un-smart HTML::Template default
448 248         342 local $Template::Alloy::QR_PRIVATE = undef;
449              
450 248         331 my $out = '';
451 248 100       903 $self->process_simple($content, $param, \$out) || die $self->error;
452              
453 226 50       621 if ($args->{'print_to'}) {
454 0         0 print {$args->{'print_to'}} $out;
  0         0  
455 0         0 return undef;
456             } else {
457 226         4177 return $out;
458             }
459             }
460              
461             ###----------------------------------------------------------------###
462              
463             1;
464              
465             __END__