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 arrays 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 Apache::Constants qw( :common );
515           use Template qw( :template );
516           use CGI;
517
518           our $VERSION = 1.59;
519
520           sub handler {
521               my $r = shift;
522
523               my $websrc = $r->dir_config('websrc_root')
524                   or return fail($r, SERVER_ERROR,
525                                  "'websrc_root' not specified");
526
527               my $template = Template->new({
528                   INCLUDE_PATH  => "$websrc/src/user:$websrc/lib",
529                   PRE_PROCESS   => 'config',
530                   OUTPUT        => $r,     # direct output to Apache request
531               });
532
533               my $params = {
534                   uri     => $r->uri,
535                   cgi     => CGI->new,
536               };
537
538               # use the path_info to determine which template file to process
539               my $file = $r->path_info;
540               $file =~ s[^/][];
541
542               $r->content_type('text/html');
543               $r->send_http_header;
544
545               $template->process($file, $params)
546                   || return fail($r, SERVER_ERROR, $template->error());
547
548               return OK;
549           }
550
551           sub fail {
552               my ($r, $status, $message) = @_;
553               $r->log_reason($message, $r->filename);
554               return $status;
555           }
556
557       The handler accepts the request and uses it to determine the
558       "websrc_root" value from the config file.  This is then used to define
559       an "INCLUDE_PATH" for a new Template object.  The URI is extracted from
560       the request and a CGI object is created.  These are both defined as
561       template variables.
562
563       The name of the template file itself is taken from the "PATH_INFO"
564       element of the request.  In this case, it would comprise the part of
565       the URL coming after "/user/bin",  e.g for "/user/bin/edit", the
566       template file would be "edit" located in "$websrc/src/user".  The
567       headers are sent and the template file is processed.  All output is
568       sent directly to the "print()" method of the Apache request object.
569

Using Plugins to Extend Functionality

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

AUTHOR

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