fixed bug in compiled code to handle undef as an allowed value - needs testing
[urisagit/Template-Simple.git] / lib / Template / Simple.pm
CommitLineData
e374d8da 1package Template::Simple;
2
3use warnings;
4use strict;
5
6use Carp ;
9d1a25cd 7use Data::Dumper ;
e374d8da 8use Scalar::Util qw( reftype ) ;
9use File::Slurp ;
10
e374d8da 11
12our $VERSION = '0.03';
13
14my %opt_defaults = (
15
16 pre_delim => qr/\[%/,
17 post_delim => qr/%\]/,
18 greedy_chunk => 0,
19# upper_case => 0,
20# lower_case => 0,
21 include_paths => [ qw( templates ) ],
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
32 while( my( $name, $default ) = each %opt_defaults ) {
33
34 $self->{$name} = defined( $opts{$name} ) ?
35 $opts{$name} : $default ;
36 }
37
38# make up the regexes to parse the markup from templates
39
40# this matches scalar markups and grabs the name
41
42 $self->{scalar_re} = qr{
43 $self->{pre_delim}
44 \s* # optional leading whitespace
45 (\w+?) # grab scalar name
46 \s* # optional trailing whitespace
47 $self->{post_delim}
48 }xi ; # case insensitive
49
50#print "RE <$self->{scalar_re}>\n" ;
51
52# this grabs the body of a chunk in either greedy or non-greedy modes
53
54 my $chunk_body = $self->{greedy_chunk} ? qr/.+/s : qr/.+?/s ;
55
56# this matches a marked chunk and grabs its name and text body
57
58 $self->{chunk_re} = qr{
59 $self->{pre_delim}
60 \s* # optional leading whitespace
61 START # required START token
62 \s+ # required whitespace
63 (\w+?) # grab the chunk name
64 \s* # optional trailing whitespace
65 $self->{post_delim}
66 ($chunk_body) # grab the chunk body
67 $self->{pre_delim}
68 \s* # optional leading whitespace
69 END # required END token
70 \s+ # required whitespace
71 \1 # match the grabbed chunk name
72 \s* # optional trailing whitespace
73 $self->{post_delim}
74 }xi ; # case insensitive
75
76#print "RE <$self->{chunk_re}>\n" ;
77
78# this matches a include markup and grabs its template name
79
80 $self->{include_re} = qr{
81 $self->{pre_delim}
82 \s* # optional leading whitespace
83 INCLUDE # required INCLUDE token
84 \s+ # required whitespace
85 (\w+?) # grab the included template name
86 \s* # optional trailing whitespace
87 $self->{post_delim}
88 }xi ; # case insensitive
89
90# load in any templates
91
92 $self->add_templates( $opts{templates} ) ;
93
94 return $self ;
95}
96
59d7205c 97sub compile {
e374d8da 98
59d7205c 99 my( $self, $template_name ) = @_ ;
100
101 my $tmpl_ref = eval {
102 $self->_get_template( $template_name ) ;
103 } ;
104
105 croak "Template::Simple $@" if $@ ;
106
107# compile a copy of the template as it will be destroyed
108
109 my $code_body = $self->_compile_chunk( '', "${$tmpl_ref}", "\t" ) ;
110
89bd07c7 111 my $source = <<CODE ;
59d7205c 112no warnings ;
113
114sub {
115 my( \$data ) = \@_ ;
116
9d1a25cd 117 my \$out ;
59d7205c 118
9d1a25cd 119$code_body
59d7205c 120 return \\\$out ;
121}
122CODE
123
89bd07c7 124#print $source ;
59d7205c 125
89bd07c7 126 my $code_ref = eval $source ;
59d7205c 127
ca30cbfe 128print $@ if $@ ;
59d7205c 129
130 $self->{compiled_cache}{$template_name} = $code_ref ;
89bd07c7 131 $self->{source_cache}{$template_name} = $source ;
132}
133
9d1a25cd 134sub _compile_chunk {
89bd07c7 135
9d1a25cd 136 my( $self, $chunk_name, $template, $indent ) = @_ ;
89bd07c7 137
9d1a25cd 138 return '' unless length $template ;
59d7205c 139
9d1a25cd 140# generate a lookup in data for this chunk name (unless it is the top
141# level). this descends down the data tree during rendering
59d7205c 142
9d1a25cd 143 my $data_init = $chunk_name ? "\$data->{$chunk_name}" : '$data' ;
59d7205c 144
9d1a25cd 145 my $code = <<CODE ;
146${indent}my \@data = $data_init ;
52705b1c 147${indent}while( \@data ) {
59d7205c 148
52705b1c 149${indent} my \$data = shift \@data ;
9d1a25cd 150${indent} if ( ref \$data eq 'ARRAY' ) {
151${indent} push \@data, \@{\$data} ;
152${indent} next ;
153${indent} }
59d7205c 154
9d1a25cd 155CODE
156
157 $indent .= "\t" ;
59d7205c 158
159# loop all nested chunks and the text separating them
160
52705b1c 161 while( my( $parsed_name, $parsed_body ) =
162 $template =~ m{$self->{chunk_re}} ) {
59d7205c 163
9d1a25cd 164# get the pre-match text and compile its scalars and text. append to the code
59d7205c 165
9d1a25cd 166 $code .= $self->_compile_scalars(
167 substr( $template, 0, $-[0] ), $indent ) ;
59d7205c 168
ca30cbfe 169# print "OFF: $-[0] $+[0]\n" ;
170# print "PRE: [", substr( $template, 0, $-[0] ), "]\n\n" ;
171# print "CHUNK: [$1] BODY [$2]\n\n" ;
172# print "TRUNC: [", substr( $template, 0, $+[0] ), "]\n\n" ;
173# print "LEFT: [$template]\n\n" ;
174
9d1a25cd 175# compile the nested chunk and append to the code
59d7205c 176
52705b1c 177 $code .= $self->_compile_chunk(
178 $parsed_name, $parsed_body, $indent
179 ) ;
59d7205c 180
7dd12000 181# chop off the pre-match and the chunk
59d7205c 182
183 substr( $template, 0, $+[0], '' ) ;
184 }
185
9d1a25cd 186# compile trailing text for scalars and append to the code
59d7205c 187
9d1a25cd 188 $code .= $self->_compile_scalars( $template, $indent ) ;
7dd12000 189
190 chop $indent ;
59d7205c 191
9d1a25cd 192# now we end the loop for this chunk
7dd12000 193 $code .= <<CODE ;
7dd12000 194$indent}
7dd12000 195CODE
59d7205c 196
59d7205c 197 return $code ;
198}
199
200sub _compile_scalars {
201
9d1a25cd 202 my( $self, $template, $indent ) = @_ ;
59d7205c 203
204# if the template is empty return no parts
205
9d1a25cd 206 return '' unless length $template ;
59d7205c 207
208 my @parts ;
209
210 while( $template =~ m{$self->{scalar_re}}g ) {
211
9d1a25cd 212# get the pre-match text before the scalar markup and generate code to
213# access the scalar
59d7205c 214
215 push( @parts,
216 dump_text( substr( $template, 0, $-[0] ) ),
217 "\$data->{$1}"
218 ) ;
ca30cbfe 219
220# truncate the matched text so the next match starts at begining of string
221
59d7205c 222 substr( $template, 0, $+[0], '' ) ;
223 }
224
225# keep any trailing text part
226
227 push @parts, dump_text( $template ) ;
228
9d1a25cd 229 my $parts_code = join( "\n$indent.\n$indent", @parts ) ;
230
231 return <<CODE ;
232
233${indent}\$out .= ref \$data ne 'HASH' ? \$data :
234${indent}$parts_code ;
235
236CODE
59d7205c 237}
238
59d7205c 239
240sub dump_text {
241
242 my( $text ) = @_ ;
243
244 return unless length $text ;
245
246 local( $Data::Dumper::Useqq ) = 1 ;
247
248 my $dumped = Dumper $text ;
249
250 $dumped =~ s/^[^"]+// ;
251 $dumped =~ s/;\n$// ;
252
253 return $dumped ;
254}
e374d8da 255
9d1a25cd 256sub get_source {
257
258 my( $self, $template_name ) = @_ ;
259
260 return $self->{source_cache}{$template_name} ;
261}
262
e374d8da 263sub render {
264
59d7205c 265 my( $self, $template_name, $data ) = @_ ;
266
7dd12000 267 my $tmpl_ref = ref $template_name eq 'SCALAR' ? $template_name : '' ;
59d7205c 268
7dd12000 269 unless( $tmpl_ref ) {
59d7205c 270
7dd12000 271# render with cached code and return if we precompiled this template
e374d8da 272
7dd12000 273 if ( my $compiled = $self->{compiled_cache}{$template_name} ) {
59d7205c 274
7dd12000 275 return $compiled->($data) ;
276 }
59d7205c 277
7dd12000 278# not compiled so get this template by name
59d7205c 279
7dd12000 280 $tmpl_ref ||= eval{ $self->_get_template($template_name) } ;
e374d8da 281
7dd12000 282# we couldn't find this template name so assume it is the template text
283
284 $tmpl_ref ||= \$template_name ;
285 }
e374d8da 286
287 my $rendered = $self->_render_includes( $tmpl_ref ) ;
288
289#print "INC EXP <$rendered>\n" ;
290
291 $rendered = eval {
292 $self->_render_chunk( $rendered, $data ) ;
293 } ;
294
295 croak "Template::Simple $@" if $@ ;
296
297 return $rendered ;
298}
299
300sub _render_includes {
301
302 my( $self, $tmpl_ref ) = @_ ;
303
304# make a copy of the initial template so we can render it.
305
306 my $rendered = ${$tmpl_ref} ;
307
308# loop until we can render no more include markups
309
310 1 while $rendered =~
311 s{$self->{include_re}}
312 { ${ $self->_get_template($1) }
313 }e ;
314
315 return \$rendered ;
316}
317
318my %renderers = (
319
320 HASH => \&_render_hash,
321 ARRAY => \&_render_array,
322 CODE => \&_render_code,
323# if no ref then data is a scalar so replace the template with just the data
324 '' => sub { \$_[2] },
325) ;
326
327
328sub _render_chunk {
329
330 my( $self, $tmpl_ref, $data ) = @_ ;
331
332#print "T ref [$tmpl_ref] [$$tmpl_ref]\n" ;
333#print "CHUNK ref [$tmpl_ref] TMPL\n<$$tmpl_ref>\n" ;
334
335#print Dumper $data ;
336
337 return \'' unless defined $data ;
338
339# now render this chunk based on the type of data
340
341 my $renderer = $renderers{reftype $data || ''} ;
342
343#print "EXP $renderer\nREF ", reftype $data, "\n" ;
344
345 die "unknown template data type '$data'\n" unless defined $renderer ;
346
347 return $self->$renderer( $tmpl_ref, $data ) ;
348}
349
350sub _render_hash {
351
352 my( $self, $tmpl_ref, $href ) = @_ ;
353
354 return $tmpl_ref unless keys %{$href} ;
355
356# we need a local copy of the template to render
357
358 my $rendered = ${$tmpl_ref} ;
359
360
361# recursively render all top level chunks in this chunk
362
363 $rendered =~ s{$self->{chunk_re}}
364 {
365 # print "CHUNK $1\nBODY\n----\n<$2>\n\n------\n" ;
ca30cbfe 366# print "CHUNK $1\nBODY\n----\n<$2>\n\n------\n" ;
367# print "pre CHUNK [$`]\n" ;
e374d8da 368 ${ $self->_render_chunk( \"$2", $href->{$1} ) }
369 }gex ;
370
371# now render scalars
372
373#print "HREF: ", Dumper $href ;
374
375 $rendered =~ s{$self->{scalar_re}}
376 {
377 # print "SCALAR $1 VAL $href->{$1}\n" ;
378 defined $href->{$1} ? $href->{$1} : ''
379 }ge ;
380
381#print "HASH REND3\n<$rendered>\n" ;
382
383 return \$rendered ;
384}
385
386sub _render_array {
387
388 my( $self, $tmpl_ref, $aref ) = @_ ;
389
390# render this $tmpl_ref for each element of the aref and join them
391
392 my $rendered ;
393
394#print "AREF: ", Dumper $aref ;
395
396 $rendered .= ${$self->_render_chunk( $tmpl_ref, $_ )} for @{$aref} ;
397
398 return \$rendered ;
399}
400
401sub _render_code {
402
403 my( $self, $tmpl_ref, $cref ) = @_ ;
404
405 my $rendered = $cref->( $tmpl_ref ) ;
406
407 die <<DIE if ref $rendered ne 'SCALAR' ;
408data callback to code didn't return a scalar or scalar reference
409DIE
410
411 return $rendered ;
412}
413
414sub add_templates {
415
416 my( $self, $tmpls ) = @_ ;
417
418#print Dumper $tmpls ;
419 return unless defined $tmpls ;
420
421 ref $tmpls eq 'HASH' or croak "templates argument is not a hash ref" ;
59d7205c 422
423# copy all the templates from the arg hash and force the values to be
424# scalar refs
e374d8da 425
59d7205c 426 @{ $self->{tmpl_cache}}{ keys %{$tmpls} } =
e374d8da 427 map ref $_ eq 'SCALAR' ? \"${$_}" : \"$_", values %{$tmpls} ;
428
59d7205c 429#print Dumper $self->{tmpl_cache} ;
e374d8da 430
431 return ;
432}
433
434sub delete_templates {
435
436 my( $self, @names ) = @_ ;
437
060b866c 438# delete all the cached stuff or just the names passed in
439
59d7205c 440 @names = keys %{$self->{tmpl_cache}} unless @names ;
e374d8da 441
060b866c 442# clear out all the caches
443# TODO: reorg these into a hash per name
444
59d7205c 445 delete @{$self->{tmpl_cache}}{ @names } ;
060b866c 446 delete @{$self->{compiled_cache}}{ @names } ;
447 delete @{$self->{source_cache}}{ @names } ;
448
449# also remove where we found it to force a fresh search
e374d8da 450
451 delete @{$self->{template_paths}}{ @names } ;
452
453 return ;
454}
455
456sub _get_template {
457
458 my( $self, $tmpl_name ) = @_ ;
459
460#print "INC $tmpl_name\n" ;
461
59d7205c 462 my $tmpls = $self->{tmpl_cache} ;
e374d8da 463
464# get the template from the cache and send it back if it was found there
465
466 my $template = $tmpls->{ $tmpl_name } ;
467 return $template if $template ;
468
469# not found, so find, slurp in and cache the template
470
471 $template = $self->_find_template( $tmpl_name ) ;
472 $tmpls->{ $tmpl_name } = $template ;
473
474 return $template ;
475}
476
477sub _find_template {
478
479 my( $self, $tmpl_name ) = @_ ;
480
481 foreach my $dir ( @{$self->{include_paths}} ) {
482
483 my $tmpl_path = "$dir/$tmpl_name.tmpl" ;
484
485#print "PATH: $tmpl_path\n" ;
486 next unless -r $tmpl_path ;
487
488# cache the path to this template
489
490 $self->{template_paths}{$tmpl_name} = $tmpl_path ;
491
492# slurp in the template file and return it as a scalar ref
493
494 return scalar read_file( $tmpl_path, scalar_ref => 1 ) ;
495 }
496
497 die <<DIE ;
498can't find template '$tmpl_name' in '@{$self->{include_paths}}'
499DIE
500
501}
502
5031; # End of Template::Simple
504
505__END__
506
507=head1 NAME
508
509Template::Simple - A simple and fast template module
510
511=head1 VERSION
512
513Version 0.03
514
515=head1 SYNOPSIS
516
517 use Template::Simple;
518
519 my $tmpl = Template::Simple->new();
520
521 my $template = <<TMPL ;
522[%INCLUDE header%]
523[%START row%]
524 [%first%] - [%second%]
525[%END row%]
526[%INCLUDE footer%]
527TMPL
528
529 my $data = {
530 header => {
531 date => 'Jan 1, 2008',
532 author => 'Me, myself and I',
533 },
534 row => [
535 {
536 first => 'row 1 value 1',
537 second => 'row 1 value 2',
538 },
539 {
540 first => 'row 2 value 1',
541 second => 'row 2 value 2',
542 },
543 ],
544 footer => {
545 modified => 'Aug 31, 2006',
546 },
547 } ;
548
549 my $rendered = $tmpl->render( $template, $data ) ;
550
551=head1 DESCRIPTION
552
553Template::Simple has these goals:
554
555=over 4
556
557=item * Support most common template operations
558
559It can recursively include other templates, replace tokens (scalars),
560recursively render nested chunks of text and render lists. By using
561simple idioms you can get conditional renderings.
562
563=item * Complete isolation of template from program code
564
565This is very important as template design can be done by different
566people than the program logic. It is rare that one person is well
567skilled in both template design and also programming.
568
569=item * Very simple template markup (only 4 markups)
570
571The only markups are C<INCLUDE>, C<START>, C<END> and C<token>. See
572MARKUP for more.
573
574=item * Easy to follow rendering rules
575
576Rendering of templates and chunks is driven from a data tree. The type
577of the data element used in an rendering controls how the rendering
578happens. The data element can be a scalar or scalar reference or an
579array, hash or code reference.
580
581=item * Efficient template rendering
582
583Rendering is very simple and uses Perl's regular expressions
584efficiently. Because the markup is so simple less processing is needed
585than many other templaters. Precompiling templates is not supported
586yet but that optimization is on the TODO list.
587
588=item * Easy user extensions
589
590User code can be called during an rendering so you can do custom
591renderings and plugins. Closures can be used so the code can have its
592own private data for use in rendering its template chunk.
593
594=back
595
596=head2 new()
597
598You create a Template::Simple by calling the class method new:
599
600 my $tmpl = Template::Simple->new() ;
601
602All the arguments to C<new()> are key/value options that change how
603the object will do renderings.
604
605=over 4
606
607=item pre_delim
608
609This option sets the string or regex that is the starting delimiter
610for all markups. You can use a plain string or a qr// but you need to
611escape (with \Q or \) any regex metachars if you want them to be plain
612chars. The default is qr/\[%/.
613
614 my $tmpl = Template::Simple->new(
615 pre_delim => '<%',
616 );
617
618 my $rendered = $tmpl->render( '<%FOO%]', 'bar' ) ;
619
620=item post_delim
621
622This option sets the string or regex that is the ending delimiter
623for all markups. You can use a plain string or a qr// but you need to
624escape (with \Q or \) any regex metachars if you want them to be plain
625chars. The default is qr/%]/.
626
627 my $tmpl = Template::Simple->new(
628 post_delim => '%>',
629 );
630
631 my $rendered = $tmpl->render( '[%FOO%>', 'bar' ) ;
632
633=item greedy_chunk
634
635This boolean option will cause the regex that grabs a chunk of text
636between the C<START/END> markups to become greedy (.+). The default is
637a not-greedy grab of the chunk text. (UNTESTED)
638
639=item templates
640
641This option lets you load templates directly into the cache of the
642Template::Simple object. This cache will be searched by the C<INCLUDE>
643markup which will be replaced by the template if found. The option
644value is a hash reference which has template names (the name in the
645C<INCLUDE> markup) for keys and their template text as their
646values. You can delete or clear templates from the object cache with
647the C<delete_template> method.
648
649
650 my $tmpl = Template::Simple->new(
651 templates => {
652
653 foo => <<FOO,
654[%baz%] is a [%quux%]
655FOO
656 bar => <<BAR,
657[%user%] is not a [%fool%]
658BAR
659 },
660 );
661
662 my $template = <<TMPL ;
663[%INCLUDE foo %]
664TMPL
665
666 my $rendered = $tmpl->render(
667 $template,
668 {
669 baz => 'blue',
670 quux => 'color,
671 }
672 ) ;
673
674=item include_paths
675
676Template::Simple can also load C<INCLUDE> templates from files. This
677option lets you set the directory paths to search for those
678files. Note that the template name in the C<INCLUDE> markup has the
679.tmpl suffix appended to it when searched for in one of these
680paths. The loaded file is cached inside the Template::Simple object
681along with any loaded by the C<templates> option.
682
683=back
684
685=head1 METHODS
686
687=head2 render
688
689This method is passed a template and a data tree and it renders it and
690returns a reference to the resulting string. The template argument can
691be a scalar or a scalar reference. The data tree argument can be any
692value allowed by Template::Simple when rendering a template. It can
693also be a blessed reference (Perl object) since
694C<Scalar::Util::reftype> is used instead of C<ref> to determine the
695data type.
696
697Note that the author recommends against passing in an object as this
698breaks encapsulation and forces your object to be (most likely) a
699hash. It would be better to create a simple method that copies the
700object contents to a hash reference and pass that. But current
701templaters allow passing in objects so that is supported here as well.
702
703 my $rendered = $tmpl->render( $template, $data ) ;
704
705=head2 add_templates
706
707This method adds templates to the object cache. It takes a list of template names and texts just like the C<templates> constructor option.
708
709 $tmpl->add_templates(
710 {
711 foo => \$foo_template,
712 bar => '[%include bar%]',
713 }
714 ) ;
715
716=head2 delete_templates
717
718This method takes a list of template names and will delete them from
719the template cache in the object. If you pass in an empty list then
720all the templates will be deleted. This can be used when you know a
721template file has been updated and you want to get it loaded back into
722the cache. Note that you can delete templates that were loaded
723directly (via the C<templates> constructor option or the
724C<add_templates> method) or loaded from a file.
725
726 # this deletes only the foo and bar templates from the object cache
727
728 $tmpl->delete_templates( qw( foo bar ) ;
729
730 # this deletes all of templates from the object cache
731
732 $tmpl->delete_templates() ;
733
734=head2 get_dependencies
735
736This method render the only C<INCLUDE> markups of a template and it
737returns a list of the file paths that were found and loaded. It is
738meant to be used to build up a dependency list of included templates
739for a main template. Typically this can be called from a script (see
740TODO) that will do this for a set of main templates and will generate
741Makefile dependencies for them. Then you can regenerate rendered
742templates only when any of their included templates have changed. It
743takes a single argument of a template.
744
745UNKNOWN: will this require a clearing of the cache or will it do the
746right thing on its own? or will it use the file path cache?
747
748 my @dependencies =
749 $tmpl->get_dependencies( '[%INCLUDE top_level%]' );
750
751=head1 MARKUP
752
753All the markups in Template::Simple use the same delimiters which are
754C<[%> and C<%]>. You can change the delimiters with the C<pre_delim>
755and C<post_delim> options in the C<new()> constructor.
756
757=head2 Tokens
758
759A token is a single markup with a C<\w+> Perl word inside. The token
760can have optional whitespace before and after it. A token is replaced
761by a value looked up in a hash with the token as the key. The hash
762lookup keeps the same case as parsed from the token markup.
763
764 [% foo %] [%BAR%]
765
766Those will be replaced by C<$href->{foo}> and C<$href->{BAR}> assuming
767C<$href> is the current data for this rendering. Tokens are only
768parsed out during hash data rendering so see Hash Data for more.
769
770=head2 Chunks
771
772Chunks are regions of text in a template that are marked off with a
773start and end markers with the same name. A chunk start marker is
774C<[%START name%]> and the end marker for that chunk is C<[%END
775name%]>. C<name> is a C<\w+> Perl word which is the name of this
776chunk. The whitespace between C<START/END> and C<name> is required and
777there is optional whitespace before C<START/END> and after the
778C<name>. C<START/END> are case insensitive but the C<name>'s case is
779kept. C<name> must match in the C<START/END> pair and it used as a key
780in a hash data rendering. Chunks are the primary way to markup
781templates for structures (sets of tokens), nesting (hashes of hashes),
782repeats (array references) and callbacks to user code. Chunks are only
783parsed out during hash data rendering so see Hash Data for more.
784
785The body of text between the C<START/END> markups is grabbed with a
786C<.+?> regular expression with the /s option enabled so it will match
787all characters. By default it will be a non-greedy grab but you can
788change that in the constructor by enabling the C<greedy_chunk> option.
789
790 [%Start FOO%]
791 [% START bar %]
792 [% field %]
793 [% end bar %]
794 [%End FOO%]
795
796=head2 Includes
797
798=head1 RENDERING RULES
799
800Template::Simple has a short list of rendering rules and they are easy
801to understand. There are two types of renderings, include rendering
802and chunk rendering. In the C<render> method, the template is an
803unnamed top level chunk of text and it first gets its C<INCLUDE>
804markups rendered. The text then undergoes a chunk rendering and a
805scalar reference to that rendered template is returned to the caller.
806
807=head2 Include Rendering
808
809Include rendering is performed one time on a top level template. When
810it is done the template is ready for chunk rendering. Any markup of
811the form C<[%INCLUDE name]%> will be replaced by the text found in the
812template C<name>. The template name is looked up in the object's
813template cache and if it is found there its text is used as the
814replacement.
815
816If a template is not found in the cache, it will be searched for in
817the list of directories in the C<include_paths> option. The file name
818will be a directory in that list appended with the template name and
819the C<.tmpl> suffix. The first template file found will be read in and
820stored in the cache. Its path is also saved and those will be returned
821in the C<get_dependencies> method. See the C<add_templates> and
822C<delete_templates> methods and the C<include_paths> option.
823
824Rendered include text can contain more C<INCLUDE> markups and they
825will also be rendered. The include rendering phase ends where there
826are no more C<INCLUDE> found.
827
828=head2 Chunk Rendering
829
830A chunk is the text found between C<START> and C<END> markups and it
831gets its named from the C<START> markup. The top level template is
832considered an unamed chunk and also gets chunk rendered.
833
834The data for a chunk determines how it will be rendered. The data can
835be a scalar or scalar reference or an array, hash or code
836reference. Since chunks can contain nested chunks, rendering will
837recurse down the data tree as it renders the chunks. Each of these
838renderings are explained below. Also see the IDIOMS and BEST PRACTICES
839section for examples and used of these renderings.
840
841=head2 Scalar Data Rendering
842
843If the current data for a chunk is a scalar or scalar reference, the
844chunk's text in the templated is replaced by the scalar's value. This
845can be used to overwrite one default section of text with from the
846data tree.
847
848=head2 Code Data Rendering
849
850If the current data for a chunk is a code reference (also called
851anonymous sub) then the code reference is called and it is passed a
852scalar reference to the that chunk's text. The code must return a
853scalar or a scalar reference and its value replaces the chunk's text
854in the template. If the code returns any other type of data it is a
855fatal error. Code rendering is how you can do custom renderings and
856plugins. A key idiom is to use closures as the data in code renderings
857and keep the required outside data in the closure.
858
859=head2 Array Data Rendering
860
861If the current data for a chunk is an array reference do a full chunk
862rendering for each value in the array. It will replace the original
863chunk text with the joined list of rendered chunks. This is how you do
864repeated sections in Template::Simple and why there is no need for any
865loop markups. Note that this means that rendering a chunk with $data
866and [ $data ] will do the exact same thing. A value of an empty array
867C<[]> will cause the chunk to be replaced by the empty string.
868
869=head2 Hash Data Rendering
870
871If the current data for a chunk is a hash reference then two phases of
872rendering happen, nested chunk rendering and token rendering. First
873nested chunks are parsed of of this chunk along with their names. Each
874parsed out chunk is rendered based on the value in the current hash
875with the nested chunk's name as the key.
876
877If a value is not found (undefined), then the nested chunk is replaced
878by the empty string. Otherwise the nested chunk is rendered according
879to the type of its data (see chunk rendering) and it is replaced by
880the rendered text.
881
882Chunk name and token lookup in the hash data is case sensitive (see
883the TODO for cased lookups).
884
885Note that to keep a plain text chunk or to just have the all of its
886markups (chunks and tokens) be deleted just pass in an empty hash
887reference C<{}> as the data for the chunk. It will be rendered but all
888markups will be replaced by the empty string.
889
890=head2 Token Rendering
891
892The second phase is token rendering. Markups of the form [%token%] are
893replaced by the value of the hash element with the token as the
894key. If a token's value is not defined it is replaced by the empty
895string. This means if a token key is missing in the hash or its value
896is undefined or its value is the empty string, the [%token%] markup
897will be deleted in the rendering.
898
899=head1 IDIOMS and BEST PRACTICES
900
901With all template systems there are better ways to do things and
902Template::Simple is no different. This section will show some ways to
903handle typical template needs while using only the 4 markups in this
904module.
905
906=head2 Conditionals
907
908This conditional idiom can be when building a fresh data tree or
909modifying an existing one.
910
911 $href->{$chunk_name} = $keep_chunk ? {} : '' ;
912
913If you are building a fresh data tree you can use this idiom to do a
914conditional chunk:
915
916 $href->{$chunk_name} = {} if $keep_chunk ;
917
918To handle an if/else conditional use two chunks, with the else chunk's
919name prefixed with NOT_ (or use any name munging you want). Then you
920set the data for either the true chunk (just the plain name) or the
921false trunk with the NOT_ name. You can use a different name for the
922else chunk if you want but keeping the names of the if/else chunks
923related is a good idea. Here are two ways to set the if/else data. The
924first one uses the same data for both the if and else chunks and the
925second one uses different data so the it uses the full if/else code
926for that.
927
928 $href->{ ($boolean ? '' : 'NOT_') . $chunk_name} = $data
929
930 if ( $boolean ) {
931 $href->{ $chunk_name} = $true_data ;
932 else {
933 $href->{ "NOT_$chunk_name" } = $false_data ;
934 }
935
936NOTE TO ALPHA USERS: i am also thinking that a non-existing key or
937undefined hash value should leave the chunk as is. then you would need
938to explicitly replace a chunk with the empty string if you wanted it
939deleted. It does affect the list of styles idiom. Any thoughts on
940this change of behavior? Since this hasn't been released it is the
941time to decide this.
942
943=head2 Chunked Includes
944
945One of the benefits of using include templates is the ability to share
946and reuse existing work. But if an included template has a top level
947named chunk, then that name would also be the same everywhere where
948this template is included. If a template included another template in
949multiple places, its data tree would use the same name for each and
950not allow unique data to be rendered for each include. A better way is
951to have the current template wrap an include markup in a named chunk
952markup. Then the data tree could use unique names for each included
953template. Here is how it would look:
954
955 [%START foo_prime%][%INCLUDE foo%][%START foo_prime%]
956 random noise
957 [%START foo_second%][%INCLUDE foo%][%START foo_second%]
958
959See the TODO section for some ideas on how to make this even more high level.
960
961=head2 Repeated Sections
962
963If you looked at the markup of Template::Simple you have noticed that
964there is no loop or repeat construct. That is because there is no need
965for one. Any chunk can be rendered in a loop just by having its
966rendering data be an anonymous array. The renderer will loop over each
967element of the array and do a fresh rendering of the chunk with this
968data. A join (on '') of the list of renderings replaces the original
969chunk and you have a repeated chunk.
970
971=head2 A List of Mixed Styles
972
973One formating style is to have a list of sections each which can have
974its own style or content. Template::Simple can do this very easily
975with just a 2 level nested chunk and an array of data for
976rendering. The outer chunk includes (or contains) each of the desired
977styles in any order. It looks like this:
978
979 [%START para_styles%]
980 [%START main_style%]
981 [%INCLUDE para_style_main%]
982 [%END main_style%]
983 [%START sub_style%]
984 [%INCLUDE para_style_sub%]
985 [%END sub_style%]
986 [%START footer_style%]
987 [%INCLUDE para_style_footer%]
988 [%END footer_style%]
989 [%END para_styles%]
990
991The other part to make this work is in the data tree. The data for
992para_styles should be a list of hashes. Each hash contains the data
993for one pargraph style which is keyed by the style's chunk name. Since
994the other styles's chunk names are not hash they are deleted. Only the
995style which has its name as a key in the hash is rendered. The data
996tree would look something like this:
997
998 [
999 {
1000 main_style => $main_data,
1001 },
1002 {
1003 sub_style => $sub_data,
1004 },
1005 {
1006 sub_style => $other_sub_data,
1007 },
1008 {
1009 footer_style => $footer_data,
1010 },
1011 ]
1012
1013=head1 TESTS
1014
1015The test scripts use a common test driver module in t/common.pl. It is
1016passed a list of hashes, each of which has the data for one test. A
1017test can create a ne Template::Simple object or use the one from the
1018previous test. The template source, the data tree and the expected
1019results are also important keys. See the test scripts for examples of
1020how to write tests using this common driver.
1021
1022=over 4
1023
1024=item name
1025
1026This is the name of the test and is used by Test::More
1027
1028=item opts
1029
1030This is a hash ref of the options passed to the Template::Simple
1031constructor. The object is not built if the C<keep_obj> key is set.
1032
1033=item keep_obj
1034
1035If set, this will make this test keep the Template::Simple object from
1036the previous test and not build a new one.
1037
1038=item template
1039
1040This is the template to render for this test. If not set, the test
1041driver will use the template from the previous test. This is useful to
1042run a series of test variants with the same template.
1043
1044=item data
1045
1046This is the data tree for the rendering of the template.
1047
1048=item expected
1049
1050This is the text that is expected after the rendering.
1051
1052=item skip
1053
1054If set, this test is skipped.
1055
1056=back
1057
1058=head1 TODO
1059
1060Even though this template system is simple, that doesn't mean it can't
1061be extended in many ways. Here are some features and designs that
1062would be good extensions which add useful functionality without adding
1063too much complexity.
1064
1065=head2 Compiled Templates
1066
1067A commonly performed optimization in template modules is to precompile
1068(really preparse) templates into a internal form that will render
1069faster. Precompiling is slower than rendering from the original
1070template which means you won't want to do it for each rendering. This
1071means it has a downside that you lose out when you want to render
1072using templates which change often. Template::Simple makes it very
1073easy to precompile as it already has the regexes to parse out the
1074markup. So instead of calling subs to do actual rendering, a
1075precompiler would call subs to generate a compiled rendering tree.
1076The rendering tree can then be run or processes with rendering data
1077passed to it. You can think of a precompiled template as having all
1078the nested chunks be replaced by nested code that does the same
1079rendering. It can still do the dynamic rendering of the data but it
1080saves the time of parsing the template souice. There are three
1081possible internal formats for the precompiled template:
1082
1083=over 4
1084
1085=item Source code
1086
1087This precompiler will generate source code that can be stored and/or
1088eval'ed. The eval'ed top level sub can then be called and passed the
1089rendering data.
1090
1091=item Closure call tree
1092
1093The internal format can be a nested set of closures. Each closure would contain
1094private data such as fixed text parts of the original template, lists
1095of other closures to run, etc. It is trivial to write a basic closure
1096generator which will make build this tree a simple task.
1097
1098=item Code ref call tree
1099
1100This format is a Perl data tree where the nodes have a code reference
1101and its args (which can be nested instances of the same
1102nodes). Instead of executing this directly, you will need a small
1103interpreter to execute all the code refs as it runs through the tree.
1104
1105This would make for a challenging project to any intermediate Perl
1106hacker. It just involves knowing recursion, data trees and code refs.
1107Contact me if you are interested in doing this.
1108
1109=back
1110
1111=head2 Cased Hash Lookups
1112
1113One possible option is to allow hash renderings to always use upper or
1114lower cased keys in their lookups.
1115
1116=head2 Render tokens before includes and chunks
1117
1118Currently tokens are rendered after includes and chunks. If tokens
1119were rendered in a pass before the others, the include and chunk names
1120could be dynamically set. This would make it harder to precompile
1121templates as too much would be dynamic, i.e. you won't know what the
1122fixed text to parse out is since anything can be included at render
1123time. But the extra flexibility of changing the include and chunk
1124names would be interesting. It could be done easily and enabled by an
1125option.
1126
1127=head2 Plugins
1128
1129There are two different potential areas in Template::Simple that could
1130use plugins. The first is with the rendering of chunkas and
1131dispatching based on the data type. This dispatch table can easily be
1132replaced by loaded modules which offer a different way to
1133render. These include the precompiled renderers mentioned above. The
1134other area is with code references as the data type. By defining a
1135closure (or a closure making) API you can create different code refs
1136for the rendering data. The range of plugins is endless some of the
1137major template modules have noticed. One idea is to make a closure
1138which contains a different Template::Simple object than the current
1139one. This will allow rendering of a nested chunk with different rules
1140than the current chunk being rendered.
1141
1142=head2 Data Escaping
1143
1144Some templaters have options to properly escape data for some types of
1145text files such as html. this can be done with some variant of the
1146_render_hash routine which also does the scalar rendering (which is
1147where data is rendered). The rendering scalars code could be factored
1148out into a set of subs one of which is used based on any escaping
1149needs.
1150
1151=head2 Data Tree is an Object
1152
1153This is a concept I don't like but it was requested so it goes into
1154the TODO file. Currently C<render> can only be passed a regular
1155(unblessed) ref (or a scalar) for its data tree. Passing in an object
1156would break encapsulation and force the object layout to be a hash
1157tree that matches the layout of the template. I doubt that most
1158objects will want to be organized to match a template. I have two
1159ideas, one is that you add a method to that object that builds up a
1160proper (unblessed) data tree to pass to C<render>. The other is by
1161subclassing C<Template::Simple> and overriding C<render> with a sub
1162that does take an object hash and it can unbless it or build a proper
1163data tree and then call C<render> in SUPER::. A quick solution is to
1164use C<reftype> (from Scalar::Utils) instead of C<ref> to allow object
1165hashes to be passed in.
1166
1167=head2 Includes and Closure Synergy
1168
1169By pairing up an include template along with code that can generate
1170the appropriate data tree for its rendering, you can create a higher
1171level template framework (the synergy). Additional code can be
1172associated with them that will handle input processing and
1173verification for the templates (e.g. web forms) that need it. A key to
1174this will be making all the closures for the data tree. This can be
1175greatly simplified by using a closure maker sub that can create all
1176the required closures.
1177
1178=head2 Metafields and UI Generation
1179
1180Taking the synergy up to a much higher level is the concept of meta
1181knowledge of fields which can generate templates, output processing
1182(data tree generation), input processing, DB backing and more. If you
1183want to discuss such grandiose wacky application schemes in a long
1184rambling mind bending conversation, please contact me.
1185
1186=head2 More Examples and Idioms
1187
1188As I convert several scripts over to this module (they all used the
1189hack version), I will add them to an examples section or possibly put
1190them in another (pod only) module. Similarly the Idioms section needs
1191rendering and could be also put into a pod module. One goal requested
1192by an early alpha tester is to keep the primary docs as simple as the
1193markup itself. This means moving all the extra stuff (and plenty of
1194that) into other pod modules. All the pod modules would be in the same
1195cpan tarball so you get all the docs and examples when you install
1196this.
1197
1198=head1 AUTHOR
1199
1200Uri Guttman, C<< <uri at sysarch.com> >>
1201
1202=head1 BUGS
1203
1204Please report any bugs or feature requests to
1205C<bug-template-simple at rt.cpan.org>, or through the web interface at
1206L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Template-Simple>.
1207I will be notified, and then you'll automatically be notified of progress on
1208your bug as I make changes.
1209
1210=head1 SUPPORT
1211
1212You can find documentation for this module with the perldoc command.
1213
1214 perldoc Template::Simple
1215
1216You can also look for information at:
1217
1218=over 4
1219
1220=item * RT: CPAN's request tracker
1221
1222L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Template-Simple>
1223
1224=item * Search CPAN
1225
1226L<http://search.cpan.org/dist/Template-Simple>
1227
1228=back
1229
1230=head1 ACKNOWLEDGEMENTS
1231
1232I wish to thank Turbo10 for their support in developing this module.
1233
1234=head1 COPYRIGHT & LICENSE
1235
1236Copyright 2006 Uri Guttman, all rights reserved.
1237
1238This program is free software; you can redistribute it and/or modify it
1239under the same terms as Perl itself.
1240
1241=cut
1242
1243
1244find templates and tests
1245
1246deep nesting tests
1247
1248greedy tests
1249
1250methods pod
1251
1252delete_templates test
1253
1254pod cleanup
1255
1256fine edit
1257
1258more tests
1259
1260slurp dependency in makefile.pl
1261