added support for token_re
[urisagit/Template-Simple.git] / lib / Template / Simple.pm
CommitLineData
f12977de 1package Template::Simple ;
e374d8da 2
f12977de 3use warnings ;
4use strict ;
e374d8da 5
6use Carp ;
9d1a25cd 7use Data::Dumper ;
f12977de 8use Scalar::Util qw( reftype blessed ) ;
e374d8da 9use File::Slurp ;
10
f12977de 11our $VERSION = '0.06';
e374d8da 12
13my %opt_defaults = (
14
15 pre_delim => qr/\[%/,
16 post_delim => qr/%\]/,
f12977de 17 token_id => qr/\w+?/,
e374d8da 18 greedy_chunk => 0,
19# upper_case => 0,
20# lower_case => 0,
f12977de 21 search_dirs => [ qw( templates ) ],
e374d8da 22) ;
23
24sub new {
25
26 my( $class, %opts ) = @_ ;
27
28 my $self = bless {}, $class ;
29
30# get all the options or defaults into the object
31
f12977de 32# support the old name 'include_paths' ;
33
34 $opts{search_dirs} ||= delete $opts{include_paths} ;
35
e374d8da 36 while( my( $name, $default ) = each %opt_defaults ) {
37
38 $self->{$name} = defined( $opts{$name} ) ?
39 $opts{$name} : $default ;
40 }
41
f12977de 42 croak "search_dirs is not an ARRAY reference" unless
43 ref $self->{search_dirs} eq 'ARRAY' ;
44
e374d8da 45# make up the regexes to parse the markup from templates
46
47# this matches scalar markups and grabs the name
48
49 $self->{scalar_re} = qr{
50 $self->{pre_delim}
51 \s* # optional leading whitespace
f12977de 52 ($self->{token_id}) # grab scalar name
e374d8da 53 \s* # optional trailing whitespace
54 $self->{post_delim}
55 }xi ; # case insensitive
56
57#print "RE <$self->{scalar_re}>\n" ;
58
59# this grabs the body of a chunk in either greedy or non-greedy modes
60
61 my $chunk_body = $self->{greedy_chunk} ? qr/.+/s : qr/.+?/s ;
62
63# this matches a marked chunk and grabs its name and text body
64
65 $self->{chunk_re} = qr{
66 $self->{pre_delim}
67 \s* # optional leading whitespace
68 START # required START token
69 \s+ # required whitespace
f12977de 70 ($self->{token_id}) # grab the chunk name
e374d8da 71 \s* # optional trailing whitespace
72 $self->{post_delim}
73 ($chunk_body) # grab the chunk body
74 $self->{pre_delim}
75 \s* # optional leading whitespace
76 END # required END token
77 \s+ # required whitespace
78 \1 # match the grabbed chunk name
79 \s* # optional trailing whitespace
80 $self->{post_delim}
81 }xi ; # case insensitive
82
83#print "RE <$self->{chunk_re}>\n" ;
84
85# this matches a include markup and grabs its template name
86
87 $self->{include_re} = qr{
88 $self->{pre_delim}
89 \s* # optional leading whitespace
90 INCLUDE # required INCLUDE token
91 \s+ # required whitespace
f12977de 92 ($self->{token_id}) # grab the included template name
e374d8da 93 \s* # optional trailing whitespace
94 $self->{post_delim}
95 }xi ; # case insensitive
96
97# load in any templates
98
99 $self->add_templates( $opts{templates} ) ;
100
101 return $self ;
102}
103
59d7205c 104sub compile {
e374d8da 105
59d7205c 106 my( $self, $template_name ) = @_ ;
107
108 my $tmpl_ref = eval {
109 $self->_get_template( $template_name ) ;
110 } ;
111
f12977de 112#print Dumper $self ;
113
59d7205c 114 croak "Template::Simple $@" if $@ ;
115
f12977de 116 my $included = $self->_render_includes( $tmpl_ref ) ;
117
59d7205c 118# compile a copy of the template as it will be destroyed
119
f12977de 120 my $code_body = $self->_compile_chunk( '', "${$included}", "\t" ) ;
59d7205c 121
89bd07c7 122 my $source = <<CODE ;
59d7205c 123no warnings ;
124
125sub {
126 my( \$data ) = \@_ ;
127
9d1a25cd 128 my \$out ;
59d7205c 129
f12977de 130 use Scalar::Util qw( reftype ) ;
131
9d1a25cd 132$code_body
59d7205c 133 return \\\$out ;
134}
135CODE
136
89bd07c7 137#print $source ;
59d7205c 138
89bd07c7 139 my $code_ref = eval $source ;
59d7205c 140
f12977de 141#print $@ if $@ ;
59d7205c 142
143 $self->{compiled_cache}{$template_name} = $code_ref ;
89bd07c7 144 $self->{source_cache}{$template_name} = $source ;
145}
146
9d1a25cd 147sub _compile_chunk {
89bd07c7 148
9d1a25cd 149 my( $self, $chunk_name, $template, $indent ) = @_ ;
89bd07c7 150
9d1a25cd 151 return '' unless length $template ;
59d7205c 152
9d1a25cd 153# generate a lookup in data for this chunk name (unless it is the top
154# level). this descends down the data tree during rendering
59d7205c 155
9d1a25cd 156 my $data_init = $chunk_name ? "\$data->{$chunk_name}" : '$data' ;
59d7205c 157
9d1a25cd 158 my $code = <<CODE ;
159${indent}my \@data = $data_init ;
52705b1c 160${indent}while( \@data ) {
59d7205c 161
52705b1c 162${indent} my \$data = shift \@data ;
f12977de 163${indent} if ( reftype \$data eq 'ARRAY' ) {
9d1a25cd 164${indent} push \@data, \@{\$data} ;
165${indent} next ;
166${indent} }
59d7205c 167
9d1a25cd 168CODE
169
170 $indent .= "\t" ;
59d7205c 171
172# loop all nested chunks and the text separating them
173
52705b1c 174 while( my( $parsed_name, $parsed_body ) =
175 $template =~ m{$self->{chunk_re}} ) {
59d7205c 176
544b9c25 177 my $chunk_left_index = $-[0] ;
178 my $chunk_right_index = $+[0] ;
179
9d1a25cd 180# get the pre-match text and compile its scalars and text. append to the code
59d7205c 181
9d1a25cd 182 $code .= $self->_compile_scalars(
544b9c25 183 substr( $template, 0, $chunk_left_index ), $indent ) ;
59d7205c 184
ca30cbfe 185# print "CHUNK: [$1] BODY [$2]\n\n" ;
544b9c25 186# print "TRUNC: [", substr( $template, 0, $chunk_right_index ), "]\n\n" ;
187# print "PRE: [", substr( $template, 0, $chunk_left_index ), "]\n\n" ;
188
189# chop off the pre-match and the chunk
190
191 substr( $template, 0, $chunk_right_index, '' ) ;
192
193# print "REMAIN: [$template]\n\n" ;
ca30cbfe 194
9d1a25cd 195# compile the nested chunk and append to the code
59d7205c 196
52705b1c 197 $code .= $self->_compile_chunk(
198 $parsed_name, $parsed_body, $indent
199 ) ;
59d7205c 200 }
201
9d1a25cd 202# compile trailing text for scalars and append to the code
59d7205c 203
9d1a25cd 204 $code .= $self->_compile_scalars( $template, $indent ) ;
7dd12000 205
206 chop $indent ;
59d7205c 207
9d1a25cd 208# now we end the loop for this chunk
7dd12000 209 $code .= <<CODE ;
7dd12000 210$indent}
7dd12000 211CODE
59d7205c 212
59d7205c 213 return $code ;
214}
215
216sub _compile_scalars {
217
9d1a25cd 218 my( $self, $template, $indent ) = @_ ;
59d7205c 219
220# if the template is empty return no parts
221
9d1a25cd 222 return '' unless length $template ;
59d7205c 223
224 my @parts ;
225
226 while( $template =~ m{$self->{scalar_re}}g ) {
227
9d1a25cd 228# get the pre-match text before the scalar markup and generate code to
229# access the scalar
59d7205c 230
231 push( @parts,
f12977de 232 _dump_text( substr( $template, 0, $-[0] ) ),
59d7205c 233 "\$data->{$1}"
234 ) ;
ca30cbfe 235
236# truncate the matched text so the next match starts at begining of string
237
59d7205c 238 substr( $template, 0, $+[0], '' ) ;
239 }
240
241# keep any trailing text part
242
f12977de 243 push @parts, _dump_text( $template ) ;
59d7205c 244
9d1a25cd 245 my $parts_code = join( "\n$indent.\n$indent", @parts ) ;
246
247 return <<CODE ;
248
f12977de 249${indent}\$out .= reftype \$data ne 'HASH' ? \$data :
9d1a25cd 250${indent}$parts_code ;
251
252CODE
59d7205c 253}
254
59d7205c 255
f12977de 256# internal sub to dump text for the template compiler. the output is
257# a legal perl double quoted string without any leading text before
258# the opening " and no trailing newline or ;
259
260sub _dump_text {
59d7205c 261
262 my( $text ) = @_ ;
263
264 return unless length $text ;
265
266 local( $Data::Dumper::Useqq ) = 1 ;
267
268 my $dumped = Dumper $text ;
269
270 $dumped =~ s/^[^"]+// ;
271 $dumped =~ s/;\n$// ;
272
273 return $dumped ;
274}
e374d8da 275
9d1a25cd 276sub get_source {
277
278 my( $self, $template_name ) = @_ ;
279
280 return $self->{source_cache}{$template_name} ;
281}
282
e374d8da 283sub render {
284
59d7205c 285 my( $self, $template_name, $data ) = @_ ;
286
7dd12000 287 my $tmpl_ref = ref $template_name eq 'SCALAR' ? $template_name : '' ;
59d7205c 288
7dd12000 289 unless( $tmpl_ref ) {
59d7205c 290
7dd12000 291# render with cached code and return if we precompiled this template
e374d8da 292
7dd12000 293 if ( my $compiled = $self->{compiled_cache}{$template_name} ) {
59d7205c 294
7dd12000 295 return $compiled->($data) ;
296 }
59d7205c 297
544b9c25 298# not compiled so try to get this template by name or
299# assume the template name are is the actual template
7dd12000 300
544b9c25 301 $tmpl_ref =
f12977de 302 eval{ $self->_get_template( $template_name ) } ||
544b9c25 303 \$template_name ;
7dd12000 304 }
e374d8da 305
306 my $rendered = $self->_render_includes( $tmpl_ref ) ;
307
308#print "INC EXP <$rendered>\n" ;
309
310 $rendered = eval {
311 $self->_render_chunk( $rendered, $data ) ;
312 } ;
313
314 croak "Template::Simple $@" if $@ ;
315
316 return $rendered ;
317}
318
319sub _render_includes {
320
321 my( $self, $tmpl_ref ) = @_ ;
322
323# make a copy of the initial template so we can render it.
324
325 my $rendered = ${$tmpl_ref} ;
326
327# loop until we can render no more include markups
328
329 1 while $rendered =~
f12977de 330 s{$self->{include_re}}{ ${ $self->_get_template($1) }}e ;
e374d8da 331
332 return \$rendered ;
333}
334
335my %renderers = (
336
f12977de 337 SCALAR => sub { return $_[2] },
338 '' => sub { return \$_[2] },
e374d8da 339 HASH => \&_render_hash,
340 ARRAY => \&_render_array,
341 CODE => \&_render_code,
342# if no ref then data is a scalar so replace the template with just the data
e374d8da 343) ;
344
345
346sub _render_chunk {
347
348 my( $self, $tmpl_ref, $data ) = @_ ;
349
350#print "T ref [$tmpl_ref] [$$tmpl_ref]\n" ;
351#print "CHUNK ref [$tmpl_ref] TMPL\n<$$tmpl_ref>\n" ;
352
353#print Dumper $data ;
354
355 return \'' unless defined $data ;
356
f12977de 357# get the type of this data. handle blessed types
358
359 my $reftype = blessed( $data ) ;
360
361#print "REF $reftype\n" ;
362
363# handle the case of a qr// which blessed returns as Regexp
364
365 if ( $reftype ) {
366
367 $reftype = reftype $data unless $reftype eq 'Regexp' ;
368 }
369 else {
370 $reftype = ref $data ;
371 }
372
373#print "REF2 $reftype\n" ;
374
e374d8da 375# now render this chunk based on the type of data
376
f12977de 377 my $renderer = $renderers{ $reftype || ''} ;
e374d8da 378
f12977de 379#print "EXP $renderer\nREF $reftype\n" ;
e374d8da 380
f12977de 381 croak "unknown template data type '$data'\n" unless defined $renderer ;
e374d8da 382
383 return $self->$renderer( $tmpl_ref, $data ) ;
384}
385
386sub _render_hash {
387
388 my( $self, $tmpl_ref, $href ) = @_ ;
389
390 return $tmpl_ref unless keys %{$href} ;
391
392# we need a local copy of the template to render
393
394 my $rendered = ${$tmpl_ref} ;
395
e374d8da 396# recursively render all top level chunks in this chunk
397
398 $rendered =~ s{$self->{chunk_re}}
399 {
400 # print "CHUNK $1\nBODY\n----\n<$2>\n\n------\n" ;
ca30cbfe 401# print "CHUNK $1\nBODY\n----\n<$2>\n\n------\n" ;
402# print "pre CHUNK [$`]\n" ;
e374d8da 403 ${ $self->_render_chunk( \"$2", $href->{$1} ) }
404 }gex ;
405
406# now render scalars
407
408#print "HREF: ", Dumper $href ;
409
410 $rendered =~ s{$self->{scalar_re}}
411 {
412 # print "SCALAR $1 VAL $href->{$1}\n" ;
413 defined $href->{$1} ? $href->{$1} : ''
414 }ge ;
415
416#print "HASH REND3\n<$rendered>\n" ;
417
418 return \$rendered ;
419}
420
421sub _render_array {
422
423 my( $self, $tmpl_ref, $aref ) = @_ ;
424
425# render this $tmpl_ref for each element of the aref and join them
426
427 my $rendered ;
428
429#print "AREF: ", Dumper $aref ;
430
431 $rendered .= ${$self->_render_chunk( $tmpl_ref, $_ )} for @{$aref} ;
432
433 return \$rendered ;
434}
435
436sub _render_code {
437
438 my( $self, $tmpl_ref, $cref ) = @_ ;
439
440 my $rendered = $cref->( $tmpl_ref ) ;
441
f12977de 442 croak <<DIE if ref $rendered ne 'SCALAR' ;
e374d8da 443data callback to code didn't return a scalar or scalar reference
444DIE
445
446 return $rendered ;
447}
448
449sub add_templates {
450
451 my( $self, $tmpls ) = @_ ;
452
453#print Dumper $tmpls ;
454 return unless defined $tmpls ;
455
456 ref $tmpls eq 'HASH' or croak "templates argument is not a hash ref" ;
59d7205c 457
458# copy all the templates from the arg hash and force the values to be
459# scalar refs
f12977de 460
461 while( my( $name, $tmpl ) = each %{$tmpls} ) {
462
463 defined $tmpl or croak "undefined template value for '$name'" ;
464
465# cache the a scalar ref of the template
466
467 $self->{tmpl_cache}{$name} = ref $tmpl eq 'SCALAR' ?
468 \"${$tmpl}" : \"$tmpl"
469 }
e374d8da 470
59d7205c 471#print Dumper $self->{tmpl_cache} ;
e374d8da 472
473 return ;
474}
475
476sub delete_templates {
477
478 my( $self, @names ) = @_ ;
479
060b866c 480# delete all the cached stuff or just the names passed in
481
59d7205c 482 @names = keys %{$self->{tmpl_cache}} unless @names ;
e374d8da 483
f12977de 484#print "NAMES @names\n" ;
060b866c 485# clear out all the caches
486# TODO: reorg these into a hash per name
487
59d7205c 488 delete @{$self->{tmpl_cache}}{ @names } ;
060b866c 489 delete @{$self->{compiled_cache}}{ @names } ;
490 delete @{$self->{source_cache}}{ @names } ;
491
492# also remove where we found it to force a fresh search
e374d8da 493
494 delete @{$self->{template_paths}}{ @names } ;
495
496 return ;
497}
498
499sub _get_template {
500
501 my( $self, $tmpl_name ) = @_ ;
502
503#print "INC $tmpl_name\n" ;
504
59d7205c 505 my $tmpls = $self->{tmpl_cache} ;
e374d8da 506
507# get the template from the cache and send it back if it was found there
508
509 my $template = $tmpls->{ $tmpl_name } ;
510 return $template if $template ;
511
512# not found, so find, slurp in and cache the template
513
514 $template = $self->_find_template( $tmpl_name ) ;
515 $tmpls->{ $tmpl_name } = $template ;
516
517 return $template ;
518}
519
520sub _find_template {
521
522 my( $self, $tmpl_name ) = @_ ;
523
f12977de 524#print "FIND $tmpl_name\n" ;
525 foreach my $dir ( @{$self->{search_dirs}} ) {
e374d8da 526
527 my $tmpl_path = "$dir/$tmpl_name.tmpl" ;
528
529#print "PATH: $tmpl_path\n" ;
f12977de 530
531 next if $tmpl_path =~ /\n/ ;
e374d8da 532 next unless -r $tmpl_path ;
533
534# cache the path to this template
535
536 $self->{template_paths}{$tmpl_name} = $tmpl_path ;
537
538# slurp in the template file and return it as a scalar ref
539
f12977de 540#print "FOUND $tmpl_name\n" ;
541
542 return read_file( $tmpl_path, scalar_ref => 1 ) ;
e374d8da 543 }
544
f12977de 545#print "CAN'T FIND $tmpl_name\n" ;
546
547 croak <<DIE ;
548can't find template '$tmpl_name' in '@{$self->{search_dirs}}'
e374d8da 549DIE
550
551}
552
5531; # End of Template::Simple
554
555__END__
556
557=head1 NAME
558
f12977de 559Template::Simple - A simple and very fast template module
e374d8da 560
561=head1 VERSION
562
563Version 0.03
564
565=head1 SYNOPSIS
566
567 use Template::Simple;
568
569 my $tmpl = Template::Simple->new();
570
f12977de 571 # here is a simple template store in a scalar
572 # the header and footer templates will be included from the cache or files.
573
574 my $template_text = <<TMPL ;
e374d8da 575[%INCLUDE header%]
576[%START row%]
577 [%first%] - [%second%]
578[%END row%]
579[%INCLUDE footer%]
580TMPL
581
f12977de 582 # this is data that will be used to render that template the keys
583 # are mapped to the chunk names (START & END markups) in the
584 # template the row is an array reference so multiple rows will be
585 # rendered usually the data tree is generated by code instead of
586 # being pure data.
587
e374d8da 588 my $data = {
589 header => {
590 date => 'Jan 1, 2008',
591 author => 'Me, myself and I',
592 },
593 row => [
594 {
595 first => 'row 1 value 1',
596 second => 'row 1 value 2',
597 },
598 {
599 first => 'row 2 value 1',
600 second => 'row 2 value 2',
601 },
602 ],
603 footer => {
604 modified => 'Aug 31, 2006',
605 },
606 } ;
607
f12977de 608 # this call renders the template with the data tree
e374d8da 609
f12977de 610 my $rendered = $tmpl->render( \$template_text, $data ) ;
e374d8da 611
f12977de 612 # here we add the template to the cache and give it a name
e374d8da 613
f12977de 614 $tmpl->add_templates( { demo => $template_text } ) ;
e374d8da 615
f12977de 616 # this compiles and then renders that template with the same data
617 # but is much faster
e374d8da 618
f12977de 619 $tmpl->compile( 'demo' ) ;
620 my $rendered = $tmpl->render( 'demo', $data ) ;
e374d8da 621
e374d8da 622
f12977de 623=head1 DESCRIPTION
e374d8da 624
f12977de 625Template::Simple is a very fast template rendering module with a
626simple markup. It can do almost any templating task and is extendable
627with user callbacks. It can render templates directly or compile them
628for more speed.
e374d8da 629
f12977de 630=head1 CONSTRUCTOR
e374d8da 631
f12977de 632=head2 new
633
e374d8da 634You create a Template::Simple by calling the class method new:
635
636 my $tmpl = Template::Simple->new() ;
637
638All the arguments to C<new()> are key/value options that change how
f12977de 639the object will render templates.
e374d8da 640
f12977de 641=head2 pre_delim
e374d8da 642
643This option sets the string or regex that is the starting delimiter
644for all markups. You can use a plain string or a qr// but you need to
645escape (with \Q or \) any regex metachars if you want them to be plain
646chars. The default is qr/\[%/.
647
648 my $tmpl = Template::Simple->new(
649 pre_delim => '<%',
650 );
651
652 my $rendered = $tmpl->render( '<%FOO%]', 'bar' ) ;
653
f12977de 654=head2 post_delim
e374d8da 655
656This option sets the string or regex that is the ending delimiter
657for all markups. You can use a plain string or a qr// but you need to
658escape (with \Q or \) any regex metachars if you want them to be plain
659chars. The default is qr/%]/.
660
661 my $tmpl = Template::Simple->new(
662 post_delim => '%>',
663 );
664
665 my $rendered = $tmpl->render( '[%FOO%>', 'bar' ) ;
666
f12977de 667=head2 token_re
668
669This option overrides the regular expression that is used match a
670token or name in the markup. It should be a qr// and you may need to
671escape (with \Q or \) any regex metachars if you want them to be plain
672chars. The default is qr/\w+?/.
673
674 my $tmpl = Template::Simple->new(
675 token_re => qr/[\w-]+?/,
676 );
677
678 my $rendered = $tmpl->render(
679 '[% id-with-hyphens %]',
680 { 'id-with-hyphens' => 'bar' }
681 ) ;
682
683=head2 greedy_chunk
e374d8da 684
685This boolean option will cause the regex that grabs a chunk of text
686between the C<START/END> markups to become greedy (.+). The default is
687a not-greedy grab of the chunk text. (UNTESTED)
688
f12977de 689=head2 templates
e374d8da 690
691This option lets you load templates directly into the cache of the
f12977de 692Template::Simple object. See <TEMPLATE CACHE> for more on this.
e374d8da 693
694 my $tmpl = Template::Simple->new(
695 templates => {
e374d8da 696 foo => <<FOO,
697[%baz%] is a [%quux%]
698FOO
699 bar => <<BAR,
700[%user%] is not a [%fool%]
701BAR
702 },
703 );
704
f12977de 705=head2 search_dirs, include_paths
e374d8da 706
f12977de 707This option lets you set the directory paths to search for template
708files. Its value is an array reference with the paths. Its default is
709'templates'.
e374d8da 710
f12977de 711 my $tmpl = Template::Simple->new(
712 search_dirs => [ qw(
713 templates
714 templates/deeper
715 ) ],
716 ) ;
e374d8da 717
f12977de 718NOTE: This option was called C<include_paths> but since it is used to
719locate named templates as well as included ones, it was changed to
720C<search_dirs>. The older name C<include_paths> is still supported
721but new code should use C<search_dirs>.
e374d8da 722
723=head1 METHODS
724
725=head2 render
726
727This method is passed a template and a data tree and it renders it and
f12977de 728returns a reference to the resulting string.
729
730If the template argument is a scalar reference, then it is the
731template text to be rendered. A scalar template argument is first
732assumed to be a template name which is searched for in the template
733cache and the compiled template caches. If found in there it is used
734as the template. If not found there, it is searched for in the
735directories of the C<search_dirs>. Finally if not found, it will be
736used as the template text.
737
738The data tree argument can be any value allowed by Template::Simple
739when rendering a template. It can also be a blessed reference (Perl
740object) since C<Scalar::Util::reftype> is used instead of C<ref> to
741determine the data type.
e374d8da 742
743Note that the author recommends against passing in an object as this
744breaks encapsulation and forces your object to be (most likely) a
745hash. It would be better to create a simple method that copies the
f12977de 746object contents to a hash reference and pass that. But other current
e374d8da 747templaters allow passing in objects so that is supported here as well.
748
749 my $rendered = $tmpl->render( $template, $data ) ;
750
f12977de 751=head2 compile
752
753This method takes a template and compiles it to make it run much
754faster. Its only argument is a template name and that is used to
755locate the template in the object cache or it is loaded from a file
756(with the same search technique as regular rendering). The compiled
757template is stored in its own cache and can be rendered by a call to
758the render method and passing the name and the data tree.
759
760 $tmpl->compile( 'foo' ) ;
761 my $rendered = $tmpl->render( 'foo', $data ) ;
762
763There are a couple of restrictions to compiled templates. They don't
764support code references in the data tree (that may get supported in
765the future). Also since the include expansion happens one time during
766the compiling, any changes to the template or its includes will not be
767detected when rendering a compiled template. You need to re-compile a
768template to force it to use changed templates. Note that you may need
769to delete templates from the object cache (with the delete_templates
770method) to force them to be reloaded from files.
771
e374d8da 772=head2 add_templates
773
f12977de 774This method adds templates to the object cache. It takes a list of
775template names and texts just like the C<templates> constructor
776option. These templates are located by name when compiling or
777rendering.
e374d8da 778
779 $tmpl->add_templates(
780 {
781 foo => \$foo_template,
782 bar => '[%include bar%]',
783 }
784 ) ;
785
786=head2 delete_templates
787
788This method takes a list of template names and will delete them from
f12977de 789the template cache in the object. If you pass no arguments then all
790the cached templates will be deleted. This can be used when you know
791a template file has been updated and you want to get it loaded back
792into the cache.
e374d8da 793
794 # this deletes only the foo and bar templates from the object cache
795
796 $tmpl->delete_templates( qw( foo bar ) ;
797
798 # this deletes all of templates from the object cache
799
800 $tmpl->delete_templates() ;
801
f12977de 802=head2 get_source
803
804 $tmpl->get_source( 'bar' ) ;
805
806This method is passed a compiled template name and returns the
807generated Perl source for a compiled template. You can compile a
808template and paste the generated source (a single sub per template)
809into another program. The sub can be called and passed a data tree and
810return a rendered template. It saves the compile time for that
811template but it still needs to be compiled by Perl. This method is
812also useful for debugging the template compiler.
813
814=head1 TEMPLATE CACHE
815
816This cache is stored in the object and will be searched to find any
817template by name. It is initially loaded via the C<templates> option
818to new and more can be added with the C<add_templates> method. You can
819delete templates from the cache with the C<delete_templates>
820method. Compiled templates have their own cache in the
821module. Deleting a template also deletes it from the compiled cache.
822
823=head1 INCLUDE EXPANSION
e374d8da 824
f12977de 825Before a template is either rendered or compiled it undergoes include
826expansion. All include markups are replaced by a templated located in
827the cache or from a file. Included templates can include other
828templates. This expansion keeps going until no more includes are
829found.
e374d8da 830
f12977de 831=head1 LOCATING TEMPLATES
e374d8da 832
f12977de 833When a template needs to be loaded by name (when rendering, compiling
834or expanding includes) it is first searched for in the object cache
835(and the compiled cache for compiled templates). If not found there,
836the C<templates_paths> are searched for files with that name and a
837suffix of .tmpl. If a file is found, it used and also loaded into the
838template cache in the object with the searched for name as its key.
e374d8da 839
840=head1 MARKUP
841
842All the markups in Template::Simple use the same delimiters which are
843C<[%> and C<%]>. You can change the delimiters with the C<pre_delim>
844and C<post_delim> options in the C<new()> constructor.
845
846=head2 Tokens
847
848A token is a single markup with a C<\w+> Perl word inside. The token
849can have optional whitespace before and after it. A token is replaced
850by a value looked up in a hash with the token as the key. The hash
f12977de 851lookup keeps the same case as parsed from the token markup. You can
852override the regular expression used to match a token with the
853C<token_id> option.
e374d8da 854
855 [% foo %] [%BAR%]
856
857Those will be replaced by C<$href->{foo}> and C<$href->{BAR}> assuming
858C<$href> is the current data for this rendering. Tokens are only
859parsed out during hash data rendering so see Hash Data for more.
860
861=head2 Chunks
862
863Chunks are regions of text in a template that are marked off with a
864start and end markers with the same name. A chunk start marker is
865C<[%START name%]> and the end marker for that chunk is C<[%END
f12977de 866name%]>. C<name> is matched with C<\w+?> and that is the name of this
e374d8da 867chunk. The whitespace between C<START/END> and C<name> is required and
868there is optional whitespace before C<START/END> and after the
869C<name>. C<START/END> are case insensitive but the C<name>'s case is
f12977de 870kept. Chunks are the primary way to markup templates for structures
871(sets of tokens), nesting (hashes of hashes), repeats (array
872references) and callbacks to user code. By default a chunk will be a
873non-greedy grab but you can change that in the constructor by enabling
874the C<greedy_chunk> option. You can override the regular expression
875used to match the chunk name with the C<token_id> option.
e374d8da 876
877 [%Start FOO%]
878 [% START bar %]
879 [% field %]
880 [% end bar %]
881 [%End FOO%]
882
883=head2 Includes
884
f12977de 885When a markup C<[%include name%]> is seen, that text is replaced by
886the template of that name. C<name> is matched with C<\w+?> which is
887the name of the template. You can override the regular expression used
888to match the include C<name> with the C<token_id> option.
889
890See C<INCLUDE EXPANSION> for more on this.
891
e374d8da 892=head1 RENDERING RULES
893
894Template::Simple has a short list of rendering rules and they are easy
895to understand. There are two types of renderings, include rendering
896and chunk rendering. In the C<render> method, the template is an
897unnamed top level chunk of text and it first gets its C<INCLUDE>
898markups rendered. The text then undergoes a chunk rendering and a
899scalar reference to that rendered template is returned to the caller.
900
901=head2 Include Rendering
902
f12977de 903All include file rendering happens before any other rendering is
904done. After this phase, the rendered template will not have
905C<[%include name%]> markups in it.
e374d8da 906
907=head2 Chunk Rendering
908
f12977de 909A chunk is the text found between matching C<START> and C<END> markups
910and it gets its name from the C<START> markup. The top level template
911is considered an unamed chunk and also gets chunk rendered.
e374d8da 912
913The data for a chunk determines how it will be rendered. The data can
914be a scalar or scalar reference or an array, hash or code
915reference. Since chunks can contain nested chunks, rendering will
916recurse down the data tree as it renders the chunks. Each of these
917renderings are explained below. Also see the IDIOMS and BEST PRACTICES
918section for examples and used of these renderings.
919
f12977de 920=over 4
e374d8da 921
f12977de 922=item Hash Data Rendering
e374d8da 923
924If the current data for a chunk is a hash reference then two phases of
925rendering happen, nested chunk rendering and token rendering. First
926nested chunks are parsed of of this chunk along with their names. Each
927parsed out chunk is rendered based on the value in the current hash
928with the nested chunk's name as the key.
929
930If a value is not found (undefined), then the nested chunk is replaced
931by the empty string. Otherwise the nested chunk is rendered according
932to the type of its data (see chunk rendering) and it is replaced by
933the rendered text.
934
f12977de 935Chunk name and token lookup in the hash data is case sensitive.
e374d8da 936
937Note that to keep a plain text chunk or to just have the all of its
938markups (chunks and tokens) be deleted just pass in an empty hash
939reference C<{}> as the data for the chunk. It will be rendered but all
940markups will be replaced by the empty string.
941
e374d8da 942The second phase is token rendering. Markups of the form [%token%] are
943replaced by the value of the hash element with the token as the
944key. If a token's value is not defined it is replaced by the empty
945string. This means if a token key is missing in the hash or its value
946is undefined or its value is the empty string, the [%token%] markup
947will be deleted in the rendering.
948
f12977de 949=item Array Data Rendering
e374d8da 950
f12977de 951If the current data for a chunk is an array reference it will do a
952full chunk rendering for each value in the array. It will replace the
953original chunk text with the concatenated list of rendered
954chunks. This is how you do repeated sections in Template::Simple and
955why there is no need for any loop markups. Note that this means that
956rendering a chunk with $data and [ $data ] will do the exact same
957thing. A value of an empty array C<[]> will cause the chunk to be
958replaced by the empty string.
e374d8da 959
f12977de 960=item Scalar Data Rendering
e374d8da 961
f12977de 962If the current data for a chunk is a scalar or scalar reference, the
963entire chunk is replaced by the scalar's value. This can be used to
964overwrite one default section of text with from the data tree.
e374d8da 965
f12977de 966=item Code Data Rendering
e374d8da 967
f12977de 968If the current data for a chunk is a code reference (also called
969anonymous sub) then the code reference is called and it is passed a
970scalar reference to the that chunk's text. The code must return a
971scalar or a scalar reference and its value replaces the chunk's text
972in the template. If the code returns any other type of data it is a
973fatal error. Code rendering is how you can do custom renderings and
974plugins. A key idiom is to use closures as the data in code renderings
975and keep the required outside data in the closure.
e374d8da 976
f12977de 977=back
e374d8da 978
f12977de 979=head1 DESIGN GOALS
e374d8da 980
981=over 4
982
f12977de 983=item * High speed
e374d8da 984
f12977de 985When using compiled templates T::S is one of the fastest template
986tools around. There is a benchmark script in the extras/ directory
987comparing it to Template `Toolkit and Template::Teeny
e374d8da 988
f12977de 989=item * Support most common template operations
e374d8da 990
f12977de 991It can recursively include other templates, replace tokens (scalars),
992recursively render nested chunks of text and render lists. By using
993simple idioms you can get conditional renderings.
e374d8da 994
f12977de 995=item * Complete isolation of template from program code
e374d8da 996
f12977de 997Template design and programming the data logic can be done by
998different people. Templates and data logic can be mixed and matched
999which improves reuse and flexibility.
e374d8da 1000
f12977de 1001=item * Very simple template markup (only 4 markups)
e374d8da 1002
f12977de 1003The only markups are C<INCLUDE>, C<START>, C<END> and C<token>. See
1004MARKUP for more.
e374d8da 1005
f12977de 1006=item * Easy to follow rendering rules
e374d8da 1007
f12977de 1008Rendering of templates and chunks is driven from a data tree. The type
1009of the data element used in an rendering controls how the rendering
1010happens. The data element can be a scalar, scalar reference, or an
1011array, hash or code reference.
e374d8da 1012
f12977de 1013=item * Efficient template rendering
e374d8da 1014
f12977de 1015Rendering is very simple and uses Perl's regular expressions
1016efficiently. Because the markup is so simple less processing is needed
1017than many other templaters. You can precompile templates for even
1018faster rendering but with some minor restrictions in flexibility
e374d8da 1019
f12977de 1020=item * Easy user extensions
e374d8da 1021
f12977de 1022User code can be called during an rendering so you can do custom
1023renderings and plugins. Closures can be used so the code can have its
1024own private data for use in rendering its template chunk.
e374d8da 1025
1026=back
1027
e374d8da 1028=head1 BUGS
1029
1030Please report any bugs or feature requests to
1031C<bug-template-simple at rt.cpan.org>, or through the web interface at
1032L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Template-Simple>.
1033I will be notified, and then you'll automatically be notified of progress on
1034your bug as I make changes.
1035
e374d8da 1036=over 4
1037
1038=item * RT: CPAN's request tracker
1039
1040L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Template-Simple>
1041
1042=item * Search CPAN
1043
1044L<http://search.cpan.org/dist/Template-Simple>
1045
1046=back
1047
1048=head1 ACKNOWLEDGEMENTS
1049
1050I wish to thank Turbo10 for their support in developing this module.
1051
f12977de 1052=head2 LICENSE
e374d8da 1053
f12977de 1054 Same as Perl.
e374d8da 1055
f12977de 1056=head1 COPYRIGHT
e374d8da 1057
f12977de 1058Copyright 2011 Uri Guttman, all rights reserved.
e374d8da 1059
f12977de 1060=head2 SEE ALSO
e374d8da 1061
f12977de 1062An article on file slurping in extras/slurp_article.pod. There is
1063also a benchmarking script in extras/slurp_bench.pl.
e374d8da 1064
f12977de 1065=head1 AUTHOR
e374d8da 1066
f12977de 1067Uri Guttman, E<lt>uri@stemsystems.comE<gt>
e374d8da 1068
f12977de 1069=cut