1Template::Tutorial::WebU(s3e)r Contributed Perl DocumentaTteimopnlate::Tutorial::Web(3)
2
3
4

NAME

6       Template::Tutorial::Web - Generating Web Content Using the Template
7       Toolkit
8

Overview

10       This tutorial document provides a introduction to the Template Toolkit
11       and demonstrates some of the typical ways it may be used for generating
12       web content. It covers the generation of static pages from templates
13       using the tpage and ttree scripts and then goes on to show dynamic
14       content generation using CGI scripts and Apache/mod_perl handlers.
15
16       Various features of the Template Toolkit are introduced and described
17       briefly and explained by use of example. For further information, see
18       Template, Template::Manual and the various sections within it. e.g
19
20           perldoc Template                    # Template.pm module usage
21           perldoc Template::Manual            # index to manual
22           perldoc Template::Manual::Config    # e.g. configuration options
23
24       The documentation is also available in HTML format to read online, or
25       download from the Template Toolkit web site:
26
27           http://template-toolkit.org/docs/
28

Introduction

30       The Template Toolkit is a set of Perl modules which collectively
31       implement a template processing system.
32
33       A template is a text document with special markup tags embedded in it.
34       By default, the Template Toolkit uses '"[%"' and '"%]"' to denote the
35       start and end of a tag.  Here's an example:
36
37           [% INCLUDE header %]
38
39           People of [% planet %], your attention please.
40
41           This is [% captain %] of the
42           Galactic Hyperspace Planning Council.
43
44           As you will no doubt be aware, the plans
45           for development of the outlying regions
46           of the Galaxy require the building of a
47           hyperspatial express route through your
48           star system, and regrettably your planet
49           is one of those scheduled for destruction.
50
51           The process will take slightly less than
52           [% time %].
53
54           Thank you.
55
56           [% INCLUDE footer %]
57
58       Tags can contain simple variables (like "planet" and "captain") and
59       more complex directives that start with an upper case keyword (like
60       "INCLUDE").  A directive is an instruction that tells the template
61       processor to perform some action, like processing another template
62       ("header" and "footer" in this example) and inserting the output into
63       the current template. In fact, the simple variables we mentioned are
64       actually "GET" directives, but the "GET" keyword is optional.
65
66           People of [% planet %], your attention please.      # short form
67           People of [% GET planet %], your attention please.  # long form
68
69       Other directives include "SET" to set a variable value (the "SET"
70       keyword is also optional), "FOREACH" to iterate through a list of
71       values, and "IF", "UNLESS", "ELSIF" and "ELSE" to declare conditional
72       blocks.
73
74       The Template Toolkit processes all text files equally, regardless of
75       what kind of content they contain.  So you can use TT to generate HTML,
76       XML, CSS, Javascript, Perl, RTF, LaTeX, or any other text-based format.
77       In this tutorial, however, we'll be concentrating on generating HTML
78       for web pages.
79

Generating Static Web Content

81       Here's an example of a template used to generate an HTML document.
82
83           [%  INCLUDE header
84                 title = 'This is an HTML example';
85
86               pages = [
87                 { url   = 'http://foo.org'
88                   title = 'The Foo Organisation'
89                 }
90                 { url   = 'http://bar.org'
91                   title = 'The Bar Organisation'
92                 }
93               ]
94           %]
95              <h1>Some Interesting Links</h1>
96              <ul>
97           [%  FOREACH page IN pages %]
98                <li><a href="[% page.url %]">[% page.title %]</a>
99           [%  END %]
100              </ul>
101
102           [% INCLUDE footer %]
103
104       This example shows how the "INCLUDE" directive is used to load and
105       process separate '"header"' and '"footer"' template files, including
106       the output in the current document.  These files might look something
107       like this:
108
109       header:
110
111           <html>
112             <head>
113               <title>[% title %]</title>
114             </head>
115             <body>
116
117       footer:
118
119               <div class="copyright">
120                 &copy; Copyright 2007 Arthur Dent
121               </div>
122             </body>
123           </html>
124
125       The example also uses the "FOREACH" directive to iterate through the
126       '"pages"' list to build a table of links. In this example, we have
127       defined this list within the template to contain a number of hash
128       references, each containing a '"url"' and '"title"' member. The
129       "FOREACH" directive iterates through the list, aliasing '"page"' to
130       each item (in this case, hash array references). The "[% page.url %]"
131       and "[% page.title %]" directives then access the individual values in
132       the hash ararys and insert them into the document.
133
134   Using tpage
135       Having created a template file we can now process it to generate some
136       real output. The quickest and easiest way to do this is to use the
137       tpage script. This is provided as part of the Template Toolkit and
138       should be installed in your usual Perl bin directory.
139
140       Assuming you saved your template file as example.html, you would run
141       the command:
142
143           $ tpage example.html
144
145       This will process the template file, sending the output to "STDOUT"
146       (i.e.  whizzing past you on the screen). You may want to redirect the
147       output to a file but be careful not to specify the same name as the
148       template file, or you'll overwrite it. You may want to use one prefix
149       for your templates (e.g.  '".tt"') and another (e.g. '".html"') for the
150       output files.
151
152           $ tpage example.tt > example.html
153
154       Or you can redirect the output to another directory. e.g.
155
156           $ tpage templates/example.tt > html/example.html
157
158       The output generated would look like this:
159
160           <html>
161             <head>
162               <title>This is an HTML example</title>
163             </head>
164             <body>
165               <h1>Some Interesting Links</h1>
166               <ul>
167                 <li><a href="http://foo.org">The Foo Organsiation</a>
168                 <li><a href="http://bar.org">The Bar Organsiation</a>
169               </ul>
170               <div class="copyright">
171                 &copy; Copyright 2007 Arthur Dent
172               </div>
173             </body>
174           </html>
175
176       The header and footer template files have been included (assuming you
177       created them and they're in the current directory) and the link data
178       has been built into an HTML list.
179
180   Using ttree
181       The tpage script gives you a simple and easy way to process a single
182       template without having to write any Perl code. The
183       <ttree:Template::Tools::ttree> script, also distributed as part of the
184       Template Toolkit, provides a more flexible way to process a number of
185       template documents in one go.
186
187       The first time you run the script, it will ask you if it should create
188       a configuration file (.ttreerc) in your home directory. Answer "y" to
189       have it create the file.
190
191       The <ttree:Template::Tools::ttree> documentation describes how you can
192       change the location of this file and also explains the syntax and
193       meaning of the various options in the file. Comments are written to the
194       sample configuration file which should also help.
195
196       In brief, the configuration file describes the directories in which
197       template files are to be found ("src"), where the corresponding output
198       should be written to ("dest"), and any other directories ("lib") that
199       may contain template files that you plan to "INCLUDE" into your source
200       documents. You can also specify processing options (such as "verbose"
201       and "recurse") and provide regular expression to match files that you
202       don't want to process ("ignore", "accept")> or should be copied instead
203       of being processed as templates ("copy").
204
205       An example .ttreerc file is shown here:
206
207       $HOME/.ttreerc:
208
209           verbose
210           recurse
211
212           # this is where I keep other ttree config files
213           cfg = ~/.ttree
214
215           src  = ~/websrc/src
216           lib  = ~/websrc/lib
217           dest = ~/public_html/test
218
219           ignore = \b(CVS|RCS)\b
220           ignore = ^#
221
222       You can create many different configuration files and store them in the
223       directory specified in the "cfg" option, shown above.  You then add the
224       "-f filename" option to "ttree" to have it read that file.
225
226       When you run the script, it compares all the files in the "src"
227       directory (including those in sub-directories if the "recurse" option
228       is set), with those in the "dest" directory.  If the destination file
229       doesn't exist or has an earlier modification time than the
230       corresponding source file, then the source will be processed with the
231       output written to the destination file.  The "-a" option forces all
232       files to be processed, regardless of modification times.
233
234       The script doesn't process any of the files in the "lib" directory, but
235       it does add it to the "INCLUDE_PATH" for the template processor so that
236       it can locate these files via an "INCLUDE", "PROCESS" or "WRAPPER"
237       directive.  Thus, the "lib" directory is an excellent place to keep
238       template elements such as header, footers, etc., that aren't complete
239       documents in their own right.
240
241       You can also specify various Template Toolkit options from the
242       configuration file. Consult the ttree documentation and help summary
243       ("ttree -h") for full details. e.g.
244
245       $HOME/.ttreerc:
246
247           pre_process = config
248           interpolate
249           post_chomp
250
251       The "pre_process" option allows you to specify a template file which
252       should be processed before each file.  Unsurprisingly, there's also a
253       "post_process" option to add a template after each file.  In the
254       fragment above, we have specified that the "config" template should be
255       used as a prefix template.  We can create this file in the "lib"
256       directory and use it to define some common variables, including those
257       web page links we defined earlier and might want to re-use in other
258       templates.  We could also include an HTML header, title, or menu bar in
259       this file which would then be prepended to each and every template
260       file, but for now we'll keep all that in a separate "header" file.
261
262       $lib/config:
263
264           [% root     = '~/abw'
265              home     = "$root/index.html"
266              images   = "$root/images"
267              email    = 'abw@wardley.org'
268              graphics = 1
269              webpages = [
270                { url => 'http://foo.org', title => 'The Foo Organsiation' }
271                { url => 'http://bar.org', title => 'The Bar Organsiation' }
272              ]
273           %]
274
275       Assuming you've created or copied the "header" and "footer" files from
276       the earlier example into your "lib" directory, you can now start to
277       create web pages like the following in your "src" directory and process
278       them with "ttree".
279
280       $src/newpage.html:
281
282           [% INCLUDE header
283              title = 'Another Template Toolkit Test Page'
284           %]
285
286               <a href="[% home %]">Home</a>
287               <a href="mailto:[% email %]">Email</a>
288
289           [% IF graphics %]
290               <img src="[% images %]/logo.gif" align=right width=60 height=40>
291           [% END %]
292
293           [% INCLUDE footer %]
294
295       Here we've shown how pre-defined variables can be used as flags to
296       enable certain feature (e.g. "graphics") and to specify common items
297       such as an email address and URL's for the home page, images directory
298       and so on.  This approach allows you to define these values once so
299       that they're consistent across all pages and can easily be changed to
300       new values.
301
302       When you run ttree, you should see output similar to the following
303       (assuming you have the verbose flag set).
304
305           ttree 2.9 (Template Toolkit version 2.20)
306
307                Source: /home/abw/websrc/src
308           Destination: /home/abw/public_html/test
309          Include Path: [ /home/abw/websrc/lib ]
310                Ignore: [ \b(CVS|RCS)\b, ^# ]
311                  Copy: [  ]
312                Accept: [ * ]
313
314           + newpage.html
315
316       The "+" in front of the "newpage.html" filename shows that the file was
317       processed, with the output being written to the destination directory.
318       If you run the same command again, you'll see the following line
319       displayed instead showing a "-" and giving a reason why the file wasn't
320       processed.
321
322           - newpage.html                     (not modified)
323
324       It has detected a "newpage.html" in the destination directory which is
325       more recent than that in the source directory and so hasn't bothered to
326       waste time re-processing it.  To force all files to be processed, use
327       the "-a" option.  You can also specify one or more filenames as command
328       line arguments to "ttree":
329
330           tpage newpage.html
331
332       This is what the destination page looks like.
333
334       $dest/newpage.html:
335
336           <html>
337             <head>
338               <title>Another Template Toolkit Test Page</title>
339             </head>
340             <body>
341
342               <a href="~/abw/index.html">Home</a>
343               <a href="mailto:abw@wardley.org">Email me</a>
344               <img src="~/abw/images/logo.gif" align=right width=60 height=40>
345
346               <div class="copyright">
347                 &copy; Copyright 2007 Arthur Dent
348               </div>
349             </body>
350           </html>
351
352       You can add as many documents as you like to the "src" directory and
353       "ttree" will apply the same process to them all.  In this way, it is
354       possible to build an entire tree of static content for a web site with
355       a single command.  The added benefit is that you can be assured of
356       consistency in links, header style, or whatever else you choose to
357       implement in terms of common templates elements or variables.
358

Dynamic Content Generation Via CGI Script

360       The Template module provides a simple front-end to the Template Toolkit
361       for use in CGI scripts and Apache/mod_perl handlers. Simply "use" the
362       Template module, create an object instance with the new() method and
363       then call the process() method on the object, passing the name of the
364       template file as a parameter. The second parameter passed is a
365       reference to a hash array of variables that we want made available to
366       the template:
367
368           #!/usr/bin/perl
369           use strict;
370           use warnings;
371           use Template;
372
373           my $file = 'src/greeting.html';
374           my $vars = {
375              message  => "Hello World\n"
376           };
377
378           my $template = Template->new();
379
380           $template->process($file, $vars)
381               || die "Template process failed: ", $template->error(), "\n";
382
383       So that our scripts will work with the same template files as our
384       earlier examples, we'll can add some configuration options to the
385       constructor to tell it about our environment:
386
387           my $template->new({
388               # where to find template files
389               INCLUDE_PATH => ['/home/abw/websrc/src', '/home/abw/websrc/lib'],
390               # pre-process lib/config to define any extra values
391               PRE_PROCESS  => 'config',
392           });
393
394       Note that here we specify the "config" file as a "PRE_PROCESS" option.
395       This means that the templates we process can use the same global
396       variables defined earlier for our static pages.  We don't have to
397       replicate their definitions in this script.  However, we can supply
398       additional data and functionality specific to this script via the hash
399       of variables that we pass to the "process()" method.
400
401       These entries in this hash may contain simple text or other values,
402       references to lists, others hashes, sub-routines or objects.  The
403       Template Toolkit will automatically apply the correct procedure to
404       access these different types when you use the variables in a template.
405
406       Here's a more detailed example to look over.  Amongst the different
407       template variables we define in $vars, we create a reference to a CGI
408       object and a "get_user_projects()" sub-routine.
409
410           #!/usr/bin/perl
411           use strict;
412           use warnings;
413           use Template;
414           use CGI;
415
416           $| = 1;
417           print "Content-type: text/html\n\n";
418
419           my $file = 'userinfo.html';
420           my $vars = {
421               'version'  => 3.14,
422               'days'     => [ qw( mon tue wed thu fri sat sun ) ],
423               'worklist' => \&get_user_projects,
424               'cgi'      => CGI->new(),
425               'me'       => {
426                   'id'     => 'abw',
427                   'name'   => 'Andy Wardley',
428               },
429           };
430
431           sub get_user_projects {
432               my $user = shift;
433               my @projects = ...   # do something to retrieve data
434               return \@projects;
435           }
436
437           my $template = Template->new({
438               INCLUDE_PATH => '/home/abw/websrc/src:/home/abw/websrc/lib',
439               PRE_PROCESS  => 'config',
440           });
441
442           $template->process($file, $vars)
443               || die $template->error();
444
445       Here's a sample template file that we might create to build the output
446       for this script.
447
448       $src/userinfo.html:
449
450           [% INCLUDE header
451              title = 'Template Toolkit CGI Test'
452           %]
453
454           <a href="mailto:[% email %]">Email [% me.name %]</a>
455
456           <p>This is version [% version %]</p>
457
458           <h3>Projects</h3>
459           <ul>
460           [% FOREACH project IN worklist(me.id) %]
461              <li> <a href="[% project.url %]">[% project.name %]</a>
462           [% END %]
463           </ul>
464
465           [% INCLUDE footer %]
466
467       This example shows how we've separated the Perl implementation (code)
468       from the presentation (HTML). This not only makes them easier to
469       maintain in isolation, but also allows the re-use of existing template
470       elements such as headers and footers, etc. By using template to create
471       the output of your CGI scripts, you can give them the same consistency
472       as your static pages built via ttree or other means.
473
474       Furthermore, we can modify our script so that it processes any one of a
475       number of different templates based on some condition.  A CGI script to
476       maintain a user database, for example, might process one template to
477       provide an empty form for new users, the same form with some default
478       values set for updating an existing user record, a third template for
479       listing all users in the system, and so on.  You can use any Perl
480       functionality you care to write to implement the logic of your
481       application and then choose one or other template to generate the
482       desired output for the application state.
483

Dynamic Content Generation Via Apache/Mod_Perl Handler

485       NOTE: the Apache::Template module is available from CPAN and provides a
486       simple and easy to use Apache/mod_perl interface to the Template
487       Toolkit.  Although basic, it implements most, if not all of what is
488       described below, and it avoids the need to write your own handler.
489       However, in many cases, you'll want to write your own handler to
490       customise processing for your own need, and this section will show you
491       how to get started.
492
493       The Template module can be used from an Apache/mod_perl handler. Here's
494       an example of a typical Apache httpd.conf file:
495
496           PerlModule CGI;
497           PerlModule Template
498           PerlModule MyOrg::Apache::User
499
500           PerlSetVar websrc_root   /home/abw/websrc
501
502           <Location /user/bin>
503               SetHandler     perl-script
504               PerlHandler    MyOrg::Apache::User
505           </Location>
506
507       This defines a location called "/user/bin" to which all requests will
508       be forwarded to the "handler()" method of the "MyOrg::Apache::User"
509       module.  That module might look something like this:
510
511           package MyOrg::Apache::User;
512
513           use strict;
514           use vars qw( $VERSION );
515           use Apache::Constants qw( :common );
516           use Template qw( :template );
517           use CGI;
518
519           $VERSION = 1.59;
520
521           sub handler {
522               my $r = shift;
523
524               my $websrc = $r->dir_config('websrc_root')
525                   or return fail($r, SERVER_ERROR,
526                                  "'websrc_root' not specified");
527
528               my $template = Template->new({
529                   INCLUDE_PATH  => "$websrc/src/user:$websrc/lib",
530                   PRE_PROCESS   => 'config',
531                   OUTPUT        => $r,     # direct output to Apache request
532               });
533
534               my $params = {
535                   uri     => $r->uri,
536                   cgi     => CGI->new,
537               };
538
539               # use the path_info to determine which template file to process
540               my $file = $r->path_info;
541               $file =~ s[^/][];
542
543               $r->content_type('text/html');
544               $r->send_http_header;
545
546               $template->process($file, $params)
547                   || return fail($r, SERVER_ERROR, $template->error());
548
549               return OK;
550           }
551
552           sub fail {
553               my ($r, $status, $message) = @_;
554               $r->log_reason($message, $r->filename);
555               return $status;
556           }
557
558       The handler accepts the request and uses it to determine the
559       "websrc_root" value from the config file.  This is then used to define
560       an "INCLUDE_PATH" for a new Template object.  The URI is extracted from
561       the request and a CGI object is created.  These are both defined as
562       template variables.
563
564       The name of the template file itself is taken from the "PATH_INFO"
565       element of the request.  In this case, it would comprise the part of
566       the URL coming after "/user/bin",  e.g for "/user/bin/edit", the
567       template file would be "edit" located in "$websrc/src/user".  The
568       headers are sent and the template file is processed.  All output is
569       sent directly to the "print()" method of the Apache request object.
570

Using Plugins to Extend Functionality

572       As we've already shown, it is possible to bind Perl data and functions
573       to template variables when creating dynamic content via a CGI script or
574       Apache/mod_perl process.  The Template Toolkit also supports a plugin
575       interface which allows you define such additional data and/or
576       functionality in a separate module and then load and use it as required
577       with the "USE" directive.
578
579       The main benefit to this approach is that you can load the extension
580       into any template document, even those that are processed "statically"
581       by "tpage" or "ttree".  You don't need to write a Perl wrapper to
582       explicitly load the module and make it available via the stash.
583
584       Let's demonstrate this principle using the "DBI" plugin written by
585       Simon Matthews (available from CPAN). You can create this template in
586       your "src" directory and process it using "ttree" to see the results.
587       Of course, this example relies on the existence of the appropriate SQL
588       database but you should be able to adapt it to your own resources, or
589       at least use it as a demonstrative example of what's possible.
590
591           [% INCLUDE header
592                title = 'User Info'
593           %]
594
595           [% USE DBI('dbi:mSQL:mydbname') %]
596
597           <table border=0 width="100%">
598             <tr>
599               <th>User ID</th>
600               <th>Name</th>
601               <th>Email</th>
602             </tr>
603           [% FOREACH user IN DBI.query('SELECT * FROM user ORDER BY id') %]
604             <tr>
605               <td>[% user.id %]</td>
606               <td>[% user.name %]</td>
607               <td>[% user.email %]</td>
608             </tr>
609           [% END %]
610           </table>
611
612           [% INCLUDE footer %]
613
614       A plugin is simply a Perl module in a known location and conforming to
615       a known standard such that the Template Toolkit can find and load it
616       automatically.  You can create your own plugin by inheriting from the
617       Template::Plugin module.
618
619       Here's an example which defines some data items ("foo" and "people")
620       and also an object method ("bar").  We'll call the plugin "FooBar" for
621       want of a better name and create it in the
622       "MyOrg::Template::Plugin::FooBar" package.  We've added a "MyOrg" to
623       the regular "Template::Plugin::*" package to avoid any conflict with
624       existing plugins.
625
626           package MyOrg::Template::Plugin::FooBar;
627           use base 'Template::Plugin'
628           our $VERSION = 1.23;
629
630           sub new {
631               my ($class, $context, @params) = @_;
632
633               bless {
634                   _CONTEXT => $context,
635                   foo      => 25,
636                   people   => [ 'tom', 'dick', 'harry' ],
637               }, $class;
638           }
639
640           sub bar {
641               my ($self, @params) = @_;
642               # ...do something...
643               return $some_value;
644           }
645
646       The plugin constructor "new()" receives the class name as the first
647       parameter, as is usual in Perl, followed by a reference to something
648       called a Template::Context object. You don't need to worry too much
649       about this at the moment, other than to know that it's the main
650       processing object for the Template Toolkit. It provides access to the
651       functionality of the processor and some plugins may need to communicate
652       with it. We don't at this stage, but we'll save the reference anyway in
653       the "_CONTEXT" member. The leading underscore is a convention which
654       indicates that this item is private and the Template Toolkit won't
655       attempt to access this member. The other members defined, "foo" and
656       "people" are regular data items which will be made available to
657       templates using this plugin. Following the context reference are passed
658       any additional parameters specified with the USE directive, such as the
659       data source parameter, "dbi:mSQL:mydbname", that we used in the earlier
660       DBI example.
661
662       If you don't or can't install it to the regular place for your Perl
663       modules (perhaps because you don't have the required privileges) then
664       you can set the PERL5LIB environment variable to specify another
665       location.  If you're using "ttree" then you can add the following line
666       to your configuration file instead.
667
668       $HOME/.ttreerc:
669
670           perl5lib = /path/to/modules
671
672       One further configuration item must be added to inform the toolkit of
673       the new package name we have adopted for our plugins:
674
675       $HOME/.ttreerc:
676
677           plugin_base = 'MyOrg::Template::Plugin'
678
679       If you're writing Perl code to control the Template modules directly,
680       then this value can be passed as a configuration parameter when you
681       create the module.
682
683           use Template;
684
685           my $template = Template->new({
686               PLUGIN_BASE => 'MyOrg::Template::Plugin'
687           });
688
689       Now we can create a template which uses this plugin:
690
691           [% INCLUDE header
692              title = 'FooBar Plugin Test'
693           %]
694
695           [% USE FooBar %]
696
697           Some values available from this plugin:
698             [% FooBar.foo %] [% FooBar.bar %]
699
700           The users defined in the 'people' list:
701           [% FOREACH uid = FooBar.people %]
702             * [% uid %]
703           [% END %]
704
705           [% INCLUDE footer %]
706
707       The "foo", "bar", and "people" items of the FooBar plugin are
708       automatically resolved to the appropriate data items or method calls on
709       the underlying object.
710
711       Using this approach, it is possible to create application functionality
712       in a single module which can then be loaded and used on demand in any
713       template.  The simple interface between template directives and plugin
714       objects allows complex, dynamic content to be built from a few simple
715       template documents without knowing anything about the underlying
716       implementation.
717

AUTHOR

719       Andy Wardley <abw@wardley.org> <http://wardley.org/>
720
722       Copyright (C) 1996-2007 Andy Wardley.  All Rights Reserved.
723
724       This module is free software; you can redistribute it and/or modify it
725       under the same terms as Perl itself.
726
727
728
729perl v5.16.3                      2011-12-20        Template::Tutorial::Web(3)
Impressum