File Coverage

blib/lib/Template/Alloy/HTE.pm
Criterion Covered Total %
statement 238 301 79.0
branch 165 242 68.1
condition 59 123 47.9
subroutine 6 14 42.8
pod 10 11 90.9
total 478 691 69.1


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   24 use strict;
  3         7  
  3         103  
10 3     3   16 use warnings;
  3         6  
  3         99  
11 3     3   17 use Template::Alloy;
  3         5  
  3         20  
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 457 my $self = shift;
38 297         439 my $str_ref = shift;
39 297 50 33     1182 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     1060 local $self->{'V2EQUALS'} = $self->{'V2EQUALS'} || 0;
44 297   100     1179 local $self->{'NO_TT'} = $self->{'NO_TT'} || ($self->{'SYNTAX'} eq 'hte' ? 0 : 1);
45              
46 297         1170 local $self->{'START_TAG'} = qr{<(|!--\s*)(/?)([+=~-]?)[Tt][Mm][Pp][Ll]_(\w+)\b};
47 297 100       895 local $self->{'_start_tag'} = (! $self->{'INTERPOLATE'}) ? $self->{'START_TAG'} : qr{(?: $self->{'START_TAG'} | (\$))}sx;
48 297         514 local $self->{'_end_tag'}; # changes over time
49              
50 297         788 my $dirs = $Template::Alloy::Parse::DIRECTIVES;
51 297         443 my $aliases = $Template::Alloy::Parse::ALIASES;
52 297         681 local @{ $dirs }{ keys %$aliases } = values %$aliases; # temporarily add to the table
  297         749  
53 297         582 local @{ $self }{@Template::Alloy::CONFIG_COMPILETIME} = @{ $self }{@Template::Alloy::CONFIG_COMPILETIME};
  297         2979  
  297         1228  
54 297 50       839 delete $dirs->{'JS'} if ! $self->{'COMPILE_JS'};
55              
56 297         457 my @tree; # the parsed tree
57 297         488 my $pointer = \@tree; # pointer to current tree to handle nested blocks
58 297         408 my @state; # maintain block levels
59 297         590 local $self->{'_state'} = \@state; # allow for items to introspect (usually BLOCKS)
60 297         530 local $self->{'_no_interp'} = 0; # no interpolation in perl
61 297         638 my @in_view; # let us know if we are in a view
62             my @blocks; # storage for defined blocks
63 297         0 my @meta; # place to store any found meta information (to go into META)
64 297         432 my $post_chomp = 0; # previous post_chomp setting
65 297         407 my $continue = 0; # flag for multiple directives in the same tag
66 297         409 my $post_op = 0; # found a post-operative DIRECTIVE
67 297         1035 my $capture; # flag to start capture
68             my $func;
69 297         0 my $pre_chomp;
70 297         0 my $node;
71 297         0 my ($comment, $is_close);
72 297         913 pos($$str_ref) = 0;
73 297   66     1046 my $allow_expr = ! defined($self->{'EXPR'}) || $self->{'EXPR'}; # default is on
74              
75 297         445 while (1) {
76             ### allow for TMPL_SET foo = PROCESS foo
77 738 100       1319 if ($capture) {
78 4 50       58 $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       14 $func = $aliases->{$func} if $aliases->{$func};
81 4 50 33     21 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         14 $node = [$func, pos($$str_ref) - length($func), undef];
86              
87 4         8 push @{ $capture->[4] }, $node;
  4         11  
88 4         8 undef $capture;
89              
90             ### handle all other TMPL tags
91             } else {
92             ### find the next opening tag
93 734 100       5041 $$str_ref =~ m{ \G (.*?) $self->{'_start_tag'} }gcxs
94             || last;
95 461         1517 my ($text, $dollar) = ($1, $6);
96 461 100       1841 ($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       1068 if (length $text) {
100 190 50       405 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       507 push @$pointer, $text if length $text;
105             }
106              
107             ### handle variable interpolation ($2 eq $)
108 461 100       850 if ($dollar) {
109             ### inspect previous text chunk for escape slashes
110 32 50       82 my $n = ($text =~ m{ (\\+) $ }x) ? length($1) : 0;
111 32 50 33     72 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     126 if ($self->{'_no_interp'} || $n % 2) {
116 0         0 push @$pointer, $dollar;
117 0         0 next;
118             }
119              
120 32         75 my $not = $$str_ref =~ m{ \G ! }gcx;
121 32         47 my $mark = pos($$str_ref);
122 32         44 my $ref;
123 32 100       73 if ($$str_ref =~ m{ \G \{ }gcx) {
124 12         28 local $self->{'_operator_precedence'} = 0; # allow operators
125 12         46 local $self->{'_end_tag'} = qr{\}};
126 12         39 $ref = $self->parse_expr($str_ref);
127 12 50       95 $$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         43 local $self->{'_operator_precedence'} = 1; # no operators
131 20         60 local $Template::Alloy::Parse::QR_COMMENTS = qr{};
132 20         67 $ref = $self->parse_expr($str_ref);
133             }
134 32 50       80 $self->throw('parse', "Error while parsing for interpolated string", undef, pos($$str_ref))
135             if ! defined $ref;
136 32 100 100     106 if (! $not && $self->{'SHOW_UNDEFINED_INTERP'}) {
137 8         40 $ref = [[undef, '//', $ref, '$'.substr($$str_ref, $mark, pos($$str_ref)-$mark)], 0];
138             }
139 32         88 push @$pointer, ['GET', $mark, pos($$str_ref), $ref];
140 32         55 $post_chomp = 0; # no chomping after dollar vars
141 32         70 next;
142             }
143              
144             ### make sure we know this directive
145 429 50       923 $func = $aliases->{$func} if $aliases->{$func};
146 429 50 66     1420 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         1328 $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     1708 $pre_chomp ||= $self->{'PRE_CHOMP'};
153 429 100       780 $pre_chomp =~ y/-=~+/1230/ if $pre_chomp;
154 429 50 66     761 if ($pre_chomp && $pointer->[-1] && ! ref $pointer->[-1]) {
      33        
155 2 50       6 if ($pre_chomp == 1) { $pointer->[-1] =~ s{ (?:\n|^) [^\S\n]* \z }{}x }
  2 0       13  
    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       10 splice(@$pointer, -1, 1, ()) if ! length $pointer->[-1]; # remove the node if it is zero length
159             }
160              
161 429         744 push @$pointer, $node;
162 429 100       1779 $self->{'_end_tag'} = $comment ? qr{([+=~-]?)-->} : qr{([+=~-]?)>}; # how will this tag end
163             }
164              
165 433         1219 $$str_ref =~ m{ \G \s+ }gcx;
166              
167             ### parse remaining tag details
168 433 100       883 if (! $is_close) {
169             ### handle HT style nodes
170 361 100       1160 if ($func =~ /^(IF|ELSIF|ELSE|UNLESS|LOOP|VAR|INCLUDE)$/) {
171 307 100       781 $func = $node->[0] = 'GET' if $func eq 'VAR';
172              
173             ### handle EXPR attribute
174 307 100       1018 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       147 if (! $allow_expr) {
178 6         28 $self->throw('parse', 'EXPR are not allowed without hte mode', undef, pos($$str_ref));
179             }
180 55         117 my $quote = $1;
181 55 100       534 local $self->{'_end_tag'} = $quote ? qr{$quote\s*$self->{'_end_tag'}} : $self->{'_end_tag'};
182 55         118 $node->[3] = eval { $self->parse_expr($str_ref) };
  55         210  
183 55 100       152 if (! defined($node->[3])) {
184 2   33     37 my $err = $@ || $self->exception('parse', 'Error while looking for EXPR', undef, pos($$str_ref));
185 2 50 33     20 $err->info($err->info . " (Could be a missing close quote near expr=$quote)") if $quote && UNIVERSAL::can($err, 'info');
186 2         6 $self->throw($err);
187             }
188 53 100       125 if ($quote) {
189 45 50       280 $$str_ref =~ m{ \G $quote }gcx
190             || $self->throw('parse', "Missing close quote ($quote)", undef, pos($$str_ref));
191             }
192 53 100       177 if ($func eq 'INCLUDE') {
    100          
193 6         13 $node->[0] = 'PROCESS'; # no need to localize the stash
194 6         18 $node->[3] = [[[undef, '{}'],0], $node->[3]];
195             } elsif ($func eq 'UNLESS') {
196 4         11 $node->[0] = 'IF';
197 4         15 $node->[3] = [[undef, '!', $node->[3]], 0];
198             }
199 53 100       196 if ($self->{'AUTO_FILTER'}) {
200 4 50       13 $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         25  
  4         24  
202             }
203              
204             ### handle "normal" NAME attributes
205             } else {
206              
207 220         365 my ($name, $escape, $default);
208 220         314 while (1) {
209 474 100       1822 if ($$str_ref =~ m{ \G (\w+) \s*=\s* }gcx) {
    100          
    100          
210 112         271 my $key = lc $1;
211 112 50       476 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       238 if ($key eq 'name') {
215 54   33     179 $name ||= $val;
216             } else {
217 58 100       170 $self->throw('parse', uc($key)." not allowed in TMPL_$func tag", undef, pos($$str_ref)) if $func ne 'GET';
218 50 100 100     105 if ($key eq 'escape') { $escape ||= lc $val }
  30 100       102  
219 16   66     51 elsif ($key eq 'default') { $default ||= $val }
220 4         26 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     491 $name ||= $1;
224             } elsif ($$str_ref =~ m{ \G ([\"\']) (.*?) (?
225 12   33     47 $name ||= $2;
226             } else {
227 208         412 last;
228             }
229             }
230              
231 208 50 33     769 $self->throw('parse', 'Error while looking for NAME', undef, pos($$str_ref)) if ! defined($name) || ! length($name);
232 208 100       552 if ($func eq 'INCLUDE') {
    100          
233 20         39 $node->[0] = 'PROCESS'; # no need to localize the stash
234 20         65 $node->[3] = [[[undef, '{}'],0], $name];
235             } elsif ($func eq 'UNLESS') {
236 6         15 $node->[0] = 'IF';
237 6         20 $node->[3] = [[undef, '!', [$name, 0]], 0];
238             } else {
239 182         538 $node->[3] = [$name, 0]; # set the variable
240             }
241 208 100       464 $node->[3] = [[undef, '||', $node->[3], $default], 0] if $default;
242              
243             ### dress up node before finishing
244 208 100 100     682 $escape = lc $self->{'DEFAULT_ESCAPE'} if ! $escape && $self->{'DEFAULT_ESCAPE'};
245 208 100       494 if ($escape) {
    100          
246 26 50       56 $self->throw('parse', "ESCAPE not allowed in TMPL_$func tag", undef, pos($$str_ref)) if $func ne 'GET';
247 26 100 100     88 if ($escape eq 'html' || $escape eq '1') {
    100          
    100          
248 20         40 push @{ $node->[3] }, '|', 'html', 0;
  20         61  
249             } elsif ($escape eq 'url') {
250 2         5 push @{ $node->[3] }, '|', 'url', 0;
  2         9  
251             } elsif ($escape eq 'js') {
252 2         3 push @{ $node->[3] }, '|', 'js', 0;
  2         9  
253             }
254             } elsif ($self->{'AUTO_FILTER'}) {
255 2         6 push @{ $node->[3] }, '|', $self->{'AUTO_FILTER'}, 0;
  2         6  
256             }
257             }
258 287         538 $node->[2] = pos $$str_ref;
259              
260              
261             ### handle TT Directive extensions
262             } else {
263 54 100       144 $self->throw('parse', "Found a TT tag $func with NO_TT enabled", undef, pos($$str_ref)) if $self->{'NO_TT'};
264 50         79 $node->[3] = eval { $dirs->{$func}->[0]->($self, $str_ref, $node) };
  50         241  
265 50 50       162 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         102 $node->[2] = pos $$str_ref;
270             }
271             }
272              
273             ### handle ending tags - or continuation blocks
274 409 100 100     1756 if ($is_close || $dirs->{$func}->[4]) {
    100          
    100          
275 100 50       207 if (! @state) {
276 0         0 $self->throw('parse', "Found an $func tag while not in a block", $node, pos($$str_ref));
277             }
278 100         158 my $parent_node = pop @state;
279              
280             ### TODO - check for matching loop close name
281 100 100       228 $func = $node->[0] = 'END' if $is_close;
282              
283             ### handle continuation blocks such as elsif, else, catch etc
284 100 100       221 if ($dirs->{$func}->[4]) {
285 28         49 pop @$pointer; # we will store the node in the parent instead
286 28         68 $parent_node->[5] = $node;
287 28         47 my $parent_type = $parent_node->[0];
288 28 50       74 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       227 $pointer = (! @state) ? \@tree : $state[-1]->[4];
295              
296             ### normal end block
297 100 100       226 if (! $dirs->{$func}->[4]) {
298 72 100       250 if ($parent_node->[0] eq 'BLOCK') { # move BLOCKS to front
    50          
    50          
299 6 50 33     24 if (defined($parent_node->[3]) && @in_view) {
300 0         0 push @{ $in_view[-1] }, $parent_node;
  0         0  
301             } else {
302 6         12 push @blocks, $parent_node;
303             }
304 6 100 66     27 if ($pointer->[-1] && ! $pointer->[-1]->[6]) { # capturing doesn't remove the var
305 4         13 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         45 push @state, $node;
318 28   50     130 $pointer = $node->[4] ||= [];
319             }
320 100         199 $node->[2] = pos $$str_ref;
321              
322             ### handle block directives
323             } elsif ($dirs->{$func}->[2]) {
324 72         139 push @state, $node;
325 72   50     268 $pointer = $node->[4] ||= []; # allow future parsed nodes before END tag to end up in current node
326 72 50       166 push @in_view, [] if $func eq 'VIEW';
327 72 50       181 $self->{'_no_interp'}++ if $dirs->{$node->[0]}->[5] # allow no_interp to turn on and off
328              
329             } elsif ($func eq 'META') {
330 2         4 unshift @meta, @{ $node->[3] }; # first defined win
  2         6  
331 2         4 $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       2602 if ($$str_ref =~ m{ \G \s* $self->{'_end_tag'} }gcxs) {
    50          
337 405   66     1586 $post_chomp = $1 || $self->{'POST_CHOMP'};
338 405 100       796 $post_chomp =~ y/-=~+/1230/ if $post_chomp;
339 405         550 $continue = 0;
340 405         509 $post_op = 0;
341 405         759 next;
342              
343             ### setup capturing
344             } elsif ($node->[6]) {
345 4         9 $capture = $node;
346 4         7 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       662 unshift(@tree, @blocks) if @blocks;
356 273 100       553 unshift(@tree, ['META', 1, 1, \@meta]) if @meta;
357 273 50       579 $self->throw('parse', "Missing 0;
358              
359             ### pull off the last text portion - if any
360 273 100       653 if (pos($$str_ref) != length($$str_ref)) {
361 82         175 my $text = substr $$str_ref, pos($$str_ref);
362 82 100       178 if (! $post_chomp) { }
    50          
    0          
    0          
363 2         11 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       236 push @$pointer, $text if length $text;
367             }
368              
369 273         3409 return \@tree;
370             }
371              
372             ###----------------------------------------------------------------###
373             ### a few HTML::Template and HTML::Template::Expr routines
374              
375             sub param {
376 248     248 1 1001 my $self = shift;
377 248         376 my $args;
378 248 50       556 if (@_ == 1) {
379 248         351 my $key = shift;
380 248 50       648 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         704 $args = [%$key];
385             } else {
386 0 0       0 $self->throw('param', "Odd number of parameters") if @_ % 2;
387 0         0 $args = \@_;
388             }
389 248         598 while (@$args) {
390 198         365 my $key = shift @$args;
391 198 50       604 $key = lc $key if ! $self->{'CASE_SENSITIVE'};
392 198         707 $self->{'_vars'}->{$key} = shift @$args;
393             }
394 248         507 return;
395             }
396              
397             sub output {
398 248     248 1 839 my $self = shift;
399 248 50       666 my $args = ref($_[0]) eq 'HASH' ? shift : {@_};
400 248   50     946 my $type = $self->{'TYPE'} || '';
401              
402 248         354 my $content;
403 248 50 33     1768 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   0     565 $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     561 my $param = $self->{'_vars'} || {};
422 248 50       554 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       633 local $self->{'FILE_CACHE'} = $self->{'DOUBLE_FILE_CACHE'} ? 1 : $self->{'FILE_CACHE'};
433 248 50       454 my $cache_size = ($self->{'CACHE'}) ? undef : 0;
434 248 50 0     471 my $compile_dir = (! $self->{'FILE_CACHE'}) ? undef : $self->{'FILE_CACHE_DIR'} || $self->throw('output', 'Missing file_cache_dir');
435 248 50       455 my $stat_ttl = (! $self->{'BLIND_CACHE'}) ? undef : 60; # not sure how high to set the blind cache
436 248 50       454 $cache_size = undef if $self->{'DOUBLE_FILE_CACHE'};
437              
438 248   100     797 local $self->{'SYNTAX'} = $self->{'SYNTAX'} || 'hte';
439 248         556 local $self->{'GLOBAL_CACHE'} = $self->{'CACHE'};
440 248 50       698 local $self->{'ADD_LOCAL_PATH'} = defined($self->{'ADD_LOCAL_PATH'}) ? $self->{'ADD_LOCAL_PATH'} : 1;
441 248         470 local $self->{'CACHE_SIZE'} = $cache_size;
442 248         439 local $self->{'STAT_TTL'} = $stat_ttl;
443 248         465 local $self->{'COMPILE_DIR'} = $compile_dir;
444 248         420 local $self->{'ABSOLUTE'} = 1;
445 248         381 local $self->{'RELATIVE'} = 1;
446 248         454 local $self->{'INCLUDE_PATH'} = $self->{'PATH'};
447 248         586 local $self->{'LOWER_CASE_VAR_FALLBACK'} = ! $self->{'CASE_SENSITIVE'}; # un-smart HTML::Template default
448 248         398 local $Template::Alloy::QR_PRIVATE = undef;
449              
450 248         351 my $out = '';
451 248 100       689 $self->process_simple($content, $param, \$out) || die $self->error;
452              
453 226 50       543 if ($args->{'print_to'}) {
454 0         0 print {$args->{'print_to'}} $out;
  0         0  
455 0         0 return undef;
456             } else {
457 226         1535 return $out;
458             }
459             }
460              
461             ###----------------------------------------------------------------###
462              
463             1;
464              
465             __END__