add files
|
1 |
package Mojo::Template; |
2 |
use Mojo::Base -base; |
|
3 | ||
4 |
use Carp 'croak'; |
|
5 |
use Mojo::ByteStream; |
|
6 |
use Mojo::Exception; |
|
7 |
use Mojo::Util qw(decode encode monkey_patch slurp); |
|
8 | ||
9 |
use constant DEBUG => $ENV{MOJO_TEMPLATE_DEBUG} || 0; |
|
10 | ||
11 |
has [qw(auto_escape compiled)]; |
|
12 |
has [qw(append code prepend template)] => ''; |
|
13 |
has capture_end => 'end'; |
|
14 |
has capture_start => 'begin'; |
|
15 |
has comment_mark => '#'; |
|
16 |
has encoding => 'UTF-8'; |
|
17 |
has escape => sub { \&Mojo::Util::xml_escape }; |
|
18 |
has [qw(escape_mark expression_mark trim_mark)] => '='; |
|
19 |
has [qw(line_start replace_mark)] => '%'; |
|
20 |
has name => 'template'; |
|
21 |
has namespace => 'Mojo::Template::SandBox'; |
|
22 |
has tag_start => '<%'; |
|
23 |
has tag_end => '%>'; |
|
24 |
has tree => sub { [] }; |
|
25 | ||
26 |
sub build { |
|
27 |
my $self = shift; |
|
28 | ||
29 |
my (@lines, $cpst, $multi); |
|
30 |
my $escape = $self->auto_escape; |
|
31 |
for my $line (@{$self->tree}) { |
|
32 |
push @lines, ''; |
|
33 |
for (my $j = 0; $j < @{$line}; $j += 2) { |
|
34 |
my $type = $line->[$j]; |
|
35 |
my $value = $line->[$j + 1] || ''; |
|
36 |
my $newline = chomp $value; |
|
37 | ||
38 |
# Capture end |
|
39 |
if ($type eq 'cpen') { |
|
40 | ||
41 |
# End block |
|
42 |
$lines[-1] .= 'return Mojo::ByteStream->new($_M) }'; |
|
43 | ||
44 |
# No following code |
|
45 |
my $next = $line->[$j + 3]; |
|
46 |
$lines[-1] .= ';' if !defined $next || $next =~ /^\s*$/; |
|
47 |
} |
|
48 | ||
49 |
# Text |
|
50 |
if ($type eq 'text') { |
|
51 | ||
52 |
# Quote and fix line ending |
|
53 |
$value = quotemeta $value; |
|
54 |
$value .= '\n' if $newline; |
|
55 |
$lines[-1] .= "\$_M .= \"" . $value . "\";" if length $value; |
|
56 |
} |
|
57 | ||
58 |
# Code or multiline expression |
|
59 |
if ($type eq 'code' || $multi) { $lines[-1] .= "$value" } |
|
60 | ||
61 |
# Expression |
|
62 |
if ($type eq 'expr' || $type eq 'escp') { |
|
63 | ||
64 |
# Start |
|
65 |
unless ($multi) { |
|
66 | ||
67 |
# Escaped |
|
68 |
if (($type eq 'escp' && !$escape) || ($type eq 'expr' && $escape)) { |
|
69 |
$lines[-1] .= "\$_M .= _escape"; |
|
70 |
$lines[-1] .= " scalar $value" if length $value; |
|
71 |
} |
|
72 | ||
73 |
# Raw |
|
74 |
else { $lines[-1] .= "\$_M .= scalar $value" } |
|
75 |
} |
|
76 | ||
77 |
# Multiline |
|
78 |
$multi = !(($line->[$j + 2] // '') eq 'text' |
|
79 |
&& ($line->[$j + 3] // '') eq ''); |
|
80 | ||
81 |
# Append semicolon |
|
82 |
$lines[-1] .= ';' if !$multi && !$cpst; |
|
83 |
} |
|
84 | ||
85 |
# Capture start |
|
86 |
if ($cpst) { |
|
87 |
$lines[-1] .= $cpst; |
|
88 |
$cpst = undef; |
|
89 |
} |
|
90 |
$cpst = " sub { my \$_M = ''; " if $type eq 'cpst'; |
|
91 |
} |
|
92 |
} |
|
93 | ||
94 |
return $self->code($self->_wrap(\@lines))->tree([]); |
|
95 |
} |
|
96 | ||
97 |
sub compile { |
|
98 |
my $self = shift; |
|
99 | ||
100 |
# Compile with line directive |
|
101 |
return undef unless my $code = $self->code; |
|
102 |
my $name = $self->name; |
|
103 |
$name =~ s/"//g; |
|
104 |
my $compiled = eval qq{#line 1 "$name"\n$code}; |
|
105 |
$self->compiled($compiled) and return undef unless $@; |
|
106 | ||
107 |
# Use local stacktrace for compile exceptions |
|
108 |
return Mojo::Exception->new($@, [$self->template, $code])->trace->verbose(1); |
|
109 |
} |
|
110 | ||
111 |
sub interpret { |
|
112 |
my $self = shift; |
|
113 | ||
114 |
# Stacktrace |
|
115 |
local $SIG{__DIE__} = sub { |
|
116 |
CORE::die($_[0]) if ref $_[0]; |
|
117 |
Mojo::Exception->throw(shift, [$self->template, $self->code]); |
|
118 |
}; |
|
119 | ||
120 |
return undef unless my $compiled = $self->compiled; |
|
121 |
my $output = eval { $compiled->(@_) }; |
|
122 |
return $output unless $@; |
|
123 | ||
124 |
# Exception with template context |
|
125 |
return Mojo::Exception->new($@, [$self->template])->verbose(1); |
|
126 |
} |
|
127 | ||
128 |
sub parse { |
|
129 |
my ($self, $template) = @_; |
|
130 | ||
131 |
# Clean start |
|
132 |
my $tree = $self->template($template)->tree([])->tree; |
|
133 | ||
134 |
my $tag = $self->tag_start; |
|
135 |
my $replace = $self->replace_mark; |
|
136 |
my $expr = $self->expression_mark; |
|
137 |
my $escp = $self->escape_mark; |
|
138 |
my $cpen = $self->capture_end; |
|
139 |
my $cmnt = $self->comment_mark; |
|
140 |
my $cpst = $self->capture_start; |
|
141 |
my $trim = $self->trim_mark; |
|
142 |
my $end = $self->tag_end; |
|
143 |
my $start = $self->line_start; |
|
144 | ||
145 |
my $token_re = qr/ |
|
146 |
( |
|
147 |
\Q$tag$replace\E # Replace |
|
148 |
| |
|
149 |
\Q$tag$expr$escp\E\s*\Q$cpen\E(?!\w) # Escaped expression (end) |
|
150 |
| |
|
151 |
\Q$tag$expr$escp\E # Escaped expression |
|
152 |
| |
|
153 |
\Q$tag$expr\E\s*\Q$cpen\E(?!\w) # Expression (end) |
|
154 |
| |
|
155 |
\Q$tag$expr\E # Expression |
|
156 |
| |
|
157 |
\Q$tag$cmnt\E # Comment |
|
158 |
| |
|
159 |
\Q$tag\E\s*\Q$cpen\E(?!\w) # Code (end) |
|
160 |
| |
|
161 |
\Q$tag\E # Code |
|
162 |
| |
|
163 |
(?<!\w)\Q$cpst\E\s*\Q$trim$end\E # Trim end (start) |
|
164 |
| |
|
165 |
\Q$trim$end\E # Trim end |
|
166 |
| |
|
167 |
(?<!\w)\Q$cpst\E\s*\Q$end\E # End (start) |
|
168 |
| |
|
169 |
\Q$end\E # End |
|
170 |
) |
|
171 |
/x; |
|
172 |
my $cpen_re = qr/^(\Q$tag\E)(?:\Q$expr\E)?(?:\Q$escp\E)?\s*\Q$cpen\E/; |
|
173 |
my $end_re = qr/^(?:(\Q$cpst\E)\s*)?(\Q$trim\E)?\Q$end\E$/; |
|
174 | ||
175 |
# Split lines |
|
176 |
my $state = 'text'; |
|
177 |
my ($trimming, @capture_token); |
|
178 |
for my $line (split /\n/, $template) { |
|
179 |
$trimming = 0 if $state eq 'text'; |
|
180 | ||
181 |
# Turn Perl line into mixed line |
|
182 |
if ($state eq 'text' && $line !~ s/^(\s*)\Q$start$replace\E/$1$start/) { |
|
183 |
if ($line =~ s/^(\s*)\Q$start\E(?:(\Q$cmnt\E)|(\Q$expr\E))?//) { |
|
184 | ||
185 |
# Comment |
|
186 |
if ($2) { $line = "$tag$2 $trim$end" } |
|
187 | ||
188 |
# Expression or code |
|
189 |
else { $line = $3 ? "$1$tag$3$line $end" : "$tag$line $trim$end" } |
|
190 |
} |
|
191 |
} |
|
192 | ||
193 |
# Escaped line ending |
|
194 |
$line .= "\n" unless $line =~ s/\\\\$/\\\n/ || $line =~ s/\\$//; |
|
195 | ||
196 |
# Mixed line |
|
197 |
my @token; |
|
198 |
for my $token (split $token_re, $line) { |
|
199 | ||
200 |
# Capture end |
|
201 |
@capture_token = ('cpen', undef) if $token =~ s/$cpen_re/$1/; |
|
202 | ||
203 |
# End |
|
204 |
if ($state ne 'text' && $token =~ $end_re) { |
|
205 |
$state = 'text'; |
|
206 | ||
207 |
# Capture start |
|
208 |
splice @token, -2, 0, 'cpst', undef if $1; |
|
209 | ||
210 |
# Trim previous text |
|
211 |
if ($2) { |
|
212 |
$trimming = 1; |
|
213 |
$self->_trim(\@token); |
|
214 |
} |
|
215 | ||
216 |
# Hint at end |
|
217 |
push @token, 'text', ''; |
|
218 |
} |
|
219 | ||
220 |
# Code |
|
221 |
elsif ($token =~ /^\Q$tag\E$/) { $state = 'code' } |
|
222 | ||
223 |
# Expression |
|
224 |
elsif ($token =~ /^\Q$tag$expr\E$/) { $state = 'expr' } |
|
225 | ||
226 |
# Expression that needs to be escaped |
|
227 |
elsif ($token =~ /^\Q$tag$expr$escp\E$/) { $state = 'escp' } |
|
228 | ||
229 |
# Comment |
|
230 |
elsif ($token =~ /^\Q$tag$cmnt\E$/) { $state = 'cmnt' } |
|
231 | ||
232 |
# Text |
|
233 |
else { |
|
234 | ||
235 |
# Replace |
|
236 |
$token = $tag if $token eq "$tag$replace"; |
|
237 | ||
238 |
# Convert whitespace text to line noise |
|
239 |
if ($trimming && $token =~ s/^(\s+)//) { |
|
240 |
push @token, 'code', $1; |
|
241 |
$trimming = 0; |
|
242 |
} |
|
243 | ||
244 |
# Comments are ignored |
|
245 |
next if $state eq 'cmnt'; |
|
246 |
push @token, @capture_token, $state, $token; |
|
247 |
@capture_token = (); |
|
248 |
} |
|
249 |
} |
|
250 |
push @$tree, \@token; |
|
251 |
} |
|
252 | ||
253 |
return $self; |
|
254 |
} |
|
255 | ||
256 |
sub render { |
|
257 |
my $self = shift; |
|
258 |
return $self->parse(shift)->build->compile || $self->interpret(@_); |
|
259 |
} |
|
260 | ||
261 |
sub render_file { |
|
262 |
my ($self, $path) = (shift, shift); |
|
263 | ||
264 |
$self->name($path) unless defined $self->{name}; |
|
265 |
my $template = slurp $path; |
|
266 |
my $encoding = $self->encoding; |
|
267 |
croak qq{Template "$path" has invalid encoding.} |
|
268 |
if $encoding && !defined($template = decode $encoding, $template); |
|
269 | ||
270 |
return $self->render($template, @_); |
|
271 |
} |
|
272 | ||
273 |
sub _trim { |
|
274 |
my ($self, $line) = @_; |
|
275 | ||
276 |
# Walk line backwards |
|
277 |
for (my $j = @$line - 4; $j >= 0; $j -= 2) { |
|
278 | ||
279 |
# Skip captures |
|
280 |
next if $line->[$j] eq 'cpst' || $line->[$j] eq 'cpen'; |
|
281 | ||
282 |
# Only trim text |
|
283 |
return unless $line->[$j] eq 'text'; |
|
284 | ||
285 |
# Convert whitespace text to line noise |
|
286 |
my $value = $line->[$j + 1]; |
|
287 |
if ($line->[$j + 1] =~ s/(\s+)$//) { |
|
288 |
$value = $line->[$j + 1]; |
|
289 |
splice @$line, $j, 0, 'code', $1; |
|
290 |
} |
|
291 | ||
292 |
# Text left |
|
293 |
return if length $value; |
|
294 |
} |
|
295 |
} |
|
296 | ||
297 |
sub _wrap { |
|
298 |
my ($self, $lines) = @_; |
|
299 | ||
300 |
# Escape function |
|
301 |
my $escape = $self->escape; |
|
302 |
monkey_patch $self->namespace, _escape => sub { |
|
303 |
no warnings 'uninitialized'; |
|
304 |
ref $_[0] eq 'Mojo::ByteStream' ? $_[0] : $escape->("$_[0]"); |
|
305 |
}; |
|
306 | ||
307 |
# Wrap lines |
|
308 |
my $first = $lines->[0] ||= ''; |
|
309 |
$lines->[0] = "package @{[$self->namespace]}; use Mojo::Base -strict;"; |
|
310 |
$lines->[0] .= "sub { my \$_M = ''; @{[$self->prepend]}; do { $first"; |
|
311 |
$lines->[-1] .= "@{[$self->append]}; \$_M } };"; |
|
312 | ||
313 |
my $code = join "\n", @$lines; |
|
314 |
warn "-- Code for @{[$self->name]}\n@{[encode 'UTF-8', $code]}\n\n" if DEBUG; |
|
315 |
return $code; |
|
316 |
} |
|
317 | ||
318 |
1; |
|
319 | ||
320 |
=encoding utf8 |
|
321 | ||
322 |
=head1 NAME |
|
323 | ||
324 |
Mojo::Template - Perl-ish templates! |
|
325 | ||
326 |
=head1 SYNOPSIS |
|
327 | ||
328 |
use Mojo::Template; |
|
329 |
my $mt = Mojo::Template->new; |
|
330 | ||
331 |
# Simple |
|
332 |
my $output = $mt->render(<<'EOF'); |
|
333 |
% use Time::Piece; |
|
334 |
<!DOCTYPE html> |
|
335 |
<html> |
|
336 |
<head><title>Simple</title></head> |
|
337 |
% my $now = localtime; |
|
338 |
<body>Time: <%= $now->hms %></body> |
|
339 |
</html> |
|
340 |
EOF |
|
341 |
say $output; |
|
342 | ||
343 |
# More advanced |
|
344 |
my $output = $mt->render(<<'EOF', 23, 'foo bar'); |
|
345 |
% my ($num, $text) = @_; |
|
346 |
%= 5 * 5 |
|
347 |
<!DOCTYPE html> |
|
348 |
<html> |
|
349 |
<head><title>More advanced</title></head> |
|
350 |
<body> |
|
351 |
test 123 |
|
352 |
foo <% my $i = $num + 2; %> |
|
353 |
% for (1 .. 23) { |
|
354 |
* some text <%= $i++ %> |
|
355 |
% } |
|
356 |
</body> |
|
357 |
</html> |
|
358 |
EOF |
|
359 |
say $output; |
|
360 | ||
361 |
=head1 DESCRIPTION |
|
362 | ||
363 |
L<Mojo::Template> is a minimalistic and very Perl-ish template engine, |
|
364 |
designed specifically for all those small tasks that come up during big |
|
365 |
projects. Like preprocessing a configuration file, generating text from |
|
366 |
heredocs and stuff like that. |
|
367 | ||
368 |
See L<Mojolicious::Guides::Rendering> for information on how to generate |
|
369 |
content with the L<Mojolicious> renderer. |
|
370 | ||
371 |
=head1 SYNTAX |
|
372 | ||
373 |
For all templates L<strict>, L<warnings>, L<utf8> and Perl 5.10 features are |
|
374 |
automatically enabled. |
|
375 | ||
376 |
<% Perl code %> |
|
377 |
<%= Perl expression, replaced with result %> |
|
378 |
<%== Perl expression, replaced with XML escaped result %> |
|
379 |
<%# Comment, useful for debugging %> |
|
380 |
<%% Replaced with "<%", useful for generating templates %> |
|
381 |
% Perl code line, treated as "<% line =%>" |
|
382 |
%= Perl expression line, treated as "<%= line %>" |
|
383 |
%== Perl expression line, treated as "<%== line %>" |
|
384 |
%# Comment line, useful for debugging |
|
385 |
%% Replaced with "%", useful for generating templates |
|
386 | ||
387 |
Escaping behavior can be reversed with the L</"auto_escape"> attribute, this |
|
388 |
is the default in L<Mojolicious> C<.ep> templates for example. |
|
389 | ||
390 |
<%= Perl expression, replaced with XML escaped result %> |
|
391 |
<%== Perl expression, replaced with result %> |
|
392 | ||
393 |
L<Mojo::ByteStream> objects are always excluded from automatic escaping. |
|
394 | ||
395 |
% use Mojo::ByteStream 'b'; |
|
396 |
<%= b('<div>excluded!</div>') %> |
|
397 | ||
398 |
Newline characters can be escaped with a backslash. |
|
399 | ||
400 |
This is <%= 1 + 1 %> a\ |
|
401 |
single line |
|
402 | ||
403 |
And a backslash in front of a newline character can be escaped with another |
|
404 |
backslash. |
|
405 | ||
406 |
This will <%= 1 + 1 %> result\\ |
|
407 |
in multiple\\ |
|
408 |
lines |
|
409 | ||
410 |
Whitespace characters around tags can be trimmed with a special tag ending. |
|
411 | ||
412 |
<%= All whitespace characters around this expression will be trimmed =%> |
|
413 | ||
414 |
You can capture whole template blocks for reuse later with the C<begin> and |
|
415 |
C<end> keywords. |
|
416 | ||
417 |
<% my $block = begin %> |
|
418 |
<% my $name = shift; =%> |
|
419 |
Hello <%= $name %>. |
|
420 |
<% end %> |
|
421 |
<%= $block->('Baerbel') %> |
|
422 |
<%= $block->('Wolfgang') %> |
|
423 | ||
424 |
Perl lines can also be indented freely. |
|
425 | ||
426 |
% my $block = begin |
|
427 |
% my $name = shift; |
|
428 |
Hello <%= $name %>. |
|
429 |
% end |
|
430 |
%= $block->('Baerbel') |
|
431 |
%= $block->('Wolfgang') |
|
432 | ||
433 |
L<Mojo::Template> templates get compiled to a Perl subroutine, that means you |
|
434 |
can access arguments simply via C<@_>. |
|
435 | ||
436 |
% my ($foo, $bar) = @_; |
|
437 |
% my $x = shift; |
|
438 |
test 123 <%= $foo %> |
|
439 | ||
440 |
The compilation of templates to Perl code can make debugging a bit tricky, but |
|
441 |
L<Mojo::Template> will return L<Mojo::Exception> objects that stringify to |
|
442 |
error messages with context. |
|
443 | ||
444 |
Bareword "xx" not allowed while "strict subs" in use at template line 4. |
|
445 |
2: </head> |
|
446 |
3: <body> |
|
447 |
4: % my $i = 2; xx |
|
448 |
5: %= $i * 2 |
|
449 |
6: </body> |
|
450 | ||
451 |
=head1 ATTRIBUTES |
|
452 | ||
453 |
L<Mojo::Template> implements the following attributes. |
|
454 | ||
455 |
=head2 auto_escape |
|
456 | ||
457 |
my $bool = $mt->auto_escape; |
|
458 |
$mt = $mt->auto_escape($bool); |
|
459 | ||
460 |
Activate automatic escaping. |
|
461 | ||
462 |
=head2 append |
|
463 | ||
464 |
my $code = $mt->append; |
|
465 |
$mt = $mt->append('warn "Processed template"'); |
|
466 | ||
467 |
Append Perl code to compiled template. Note that this code should not contain |
|
468 |
newline characters, or line numbers in error messages might end up being |
|
469 |
wrong. |
|
470 | ||
471 |
=head2 capture_end |
|
472 | ||
473 |
my $end = $mt->capture_end; |
|
474 |
$mt = $mt->capture_end('end'); |
|
475 | ||
476 |
Keyword indicating the end of a capture block, defaults to C<end>. |
|
477 | ||
478 |
<% my $block = begin %> |
|
479 |
Some data! |
|
480 |
<% end %> |
|
481 | ||
482 |
=head2 capture_start |
|
483 | ||
484 |
my $start = $mt->capture_start; |
|
485 |
$mt = $mt->capture_start('begin'); |
|
486 | ||
487 |
Keyword indicating the start of a capture block, defaults to C<begin>. |
|
488 | ||
489 |
<% my $block = begin %> |
|
490 |
Some data! |
|
491 |
<% end %> |
|
492 | ||
493 |
=head2 code |
|
494 | ||
495 |
my $code = $mt->code; |
|
496 |
$mt = $mt->code($code); |
|
497 | ||
498 |
Perl code for template. |
|
499 | ||
500 |
=head2 comment_mark |
|
501 | ||
502 |
my $mark = $mt->comment_mark; |
|
503 |
$mt = $mt->comment_mark('#'); |
|
504 | ||
505 |
Character indicating the start of a comment, defaults to C<#>. |
|
506 | ||
507 |
<%# This is a comment %> |
|
508 | ||
509 |
=head2 compiled |
|
510 | ||
511 |
my $compiled = $mt->compiled; |
|
512 |
$mt = $mt->compiled($compiled); |
|
513 | ||
514 |
Compiled template code. |
|
515 | ||
516 |
=head2 encoding |
|
517 | ||
518 |
my $encoding = $mt->encoding; |
|
519 |
$mt = $mt->encoding('UTF-8'); |
|
520 | ||
521 |
Encoding used for template files. |
|
522 | ||
523 |
=head2 escape |
|
524 | ||
525 |
my $cb = $mt->escape; |
|
526 |
$mt = $mt->escape(sub { reverse $_[0] }); |
|
527 | ||
528 |
A callback used to escape the results of escaped expressions, defaults to |
|
529 |
L<Mojo::Util/"xml_escape">. |
|
530 | ||
531 |
=head2 escape_mark |
|
532 | ||
533 |
my $mark = $mt->escape_mark; |
|
534 |
$mt = $mt->escape_mark('='); |
|
535 | ||
536 |
Character indicating the start of an escaped expression, defaults to C<=>. |
|
537 | ||
538 |
<%== $foo %> |
|
539 | ||
540 |
=head2 expression_mark |
|
541 | ||
542 |
my $mark = $mt->expression_mark; |
|
543 |
$mt = $mt->expression_mark('='); |
|
544 | ||
545 |
Character indicating the start of an expression, defaults to C<=>. |
|
546 | ||
547 |
<%= $foo %> |
|
548 | ||
549 |
=head2 line_start |
|
550 | ||
551 |
my $start = $mt->line_start; |
|
552 |
$mt = $mt->line_start('%'); |
|
553 | ||
554 |
Character indicating the start of a code line, defaults to C<%>. |
|
555 | ||
556 |
% $foo = 23; |
|
557 | ||
558 |
=head2 name |
|
559 | ||
560 |
my $name = $mt->name; |
|
561 |
$mt = $mt->name('foo.mt'); |
|
562 | ||
563 |
Name of template currently being processed, defaults to C<template>. Note that |
|
564 |
this value should not contain quotes or newline characters, or error messages |
|
565 |
might end up being wrong. |
|
566 | ||
567 |
=head2 namespace |
|
568 | ||
569 |
my $namespace = $mt->namespace; |
|
570 |
$mt = $mt->namespace('main'); |
|
571 | ||
572 |
Namespace used to compile templates, defaults to C<Mojo::Template::SandBox>. |
|
573 |
Note that namespaces should only be shared very carefully between templates, |
|
574 |
since functions and global variables will not be cleared automatically. |
|
575 | ||
576 |
=head2 prepend |
|
577 | ||
578 |
my $code = $mt->prepend; |
|
579 |
$mt = $mt->prepend('my $self = shift;'); |
|
580 | ||
581 |
Prepend Perl code to compiled template. Note that this code should not contain |
|
582 |
newline characters, or line numbers in error messages might end up being |
|
583 |
wrong. |
|
584 | ||
585 |
=head2 replace_mark |
|
586 | ||
587 |
my $mark = $mt->replace_mark; |
|
588 |
$mt = $mt->replace_mark('%'); |
|
589 | ||
590 |
Character used for escaping the start of a tag or line, defaults to C<%>. |
|
591 | ||
592 |
<%% my $foo = 23; %> |
|
593 | ||
594 |
=head2 tag_start |
|
595 | ||
596 |
my $start = $mt->tag_start; |
|
597 |
$mt = $mt->tag_start('<%'); |
|
598 | ||
599 |
Characters indicating the start of a tag, defaults to C<E<lt>%>. |
|
600 | ||
601 |
<% $foo = 23; %> |
|
602 | ||
603 |
=head2 tag_end |
|
604 | ||
605 |
my $end = $mt->tag_end; |
|
606 |
$mt = $mt->tag_end('%>'); |
|
607 | ||
608 |
Characters indicating the end of a tag, defaults to C<%E<gt>>. |
|
609 | ||
610 |
<%= $foo %> |
|
611 | ||
612 |
=head2 template |
|
613 | ||
614 |
my $template = $mt->template; |
|
615 |
$mt = $mt->template($template); |
|
616 | ||
617 |
Raw unparsed template. |
|
618 | ||
619 |
=head2 tree |
|
620 | ||
621 |
my $tree = $mt->tree; |
|
622 |
$mt = $mt->tree([['text', 'foo']]); |
|
623 | ||
624 |
Template in parsed form. Note that this structure should only be used very |
|
625 |
carefully since it is very dynamic. |
|
626 | ||
627 |
=head2 trim_mark |
|
628 | ||
629 |
my $mark = $mt->trim_mark; |
|
630 |
$mt = $mt->trim_mark('-'); |
|
631 | ||
632 |
Character activating automatic whitespace trimming, defaults to C<=>. |
|
633 | ||
634 |
<%= $foo =%> |
|
635 | ||
636 |
=head1 METHODS |
|
637 | ||
638 |
L<Mojo::Template> inherits all methods from L<Mojo::Base> and implements the |
|
639 |
following new ones. |
|
640 | ||
641 |
=head2 build |
|
642 | ||
643 |
$mt = $mt->build; |
|
644 | ||
645 |
Build Perl code from tree. |
|
646 | ||
647 |
=head2 compile |
|
648 | ||
649 |
my $exception = $mt->compile; |
|
650 | ||
651 |
Compile Perl code for template. |
|
652 | ||
653 |
=head2 interpret |
|
654 | ||
655 |
my $output = $mt->interpret; |
|
656 |
my $output = $mt->interpret(@args); |
|
657 | ||
658 |
Interpret compiled template code. |
|
659 | ||
660 |
# Reuse template |
|
661 |
say $mt->render('Hello <%= $_[0] %>!', 'Bender'); |
|
662 |
say $mt->interpret('Fry'); |
|
663 |
say $mt->interpret('Leela'); |
|
664 | ||
665 |
=head2 parse |
|
666 | ||
667 |
$mt = $mt->parse($template); |
|
668 | ||
669 |
Parse template into tree. |
|
670 | ||
671 |
=head2 render |
|
672 | ||
673 |
my $output = $mt->render($template); |
|
674 |
my $output = $mt->render($template, @args); |
|
675 | ||
676 |
Render template. |
|
677 | ||
678 |
say $mt->render('Hello <%= $_[0] %>!', 'Bender'); |
|
679 | ||
680 |
=head2 render_file |
|
681 | ||
682 |
my $output = $mt->render_file('/tmp/foo.mt'); |
|
683 |
my $output = $mt->render_file('/tmp/foo.mt', @args); |
|
684 | ||
685 |
Render template file. |
|
686 | ||
687 |
=head1 DEBUGGING |
|
688 | ||
689 |
You can set the MOJO_TEMPLATE_DEBUG environment variable to get some advanced |
|
690 |
diagnostics information printed to C<STDERR>. |
|
691 | ||
692 |
MOJO_TEMPLATE_DEBUG=1 |
|
693 | ||
694 |
=head1 SEE ALSO |
|
695 | ||
696 |
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>. |
|
697 | ||
698 |
=cut |