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