|
|
Line 117: |
Line 117: |
| man Template\:\:Tutorial\:\:Web will get you this | | man Template\:\:Tutorial\:\:Web will get you this |
|
| |
|
| <H1>Template::Tutorial::Web</H1>
| | Some of these including the template tutorial listed top of this page, with wiki pages. |
| Section: User Contributed Perl Documentation (3)<BR>Updated: 2013-07-23<BR><A HREF="#index">Index</A>
| |
| <A HREF="http://localhost/cgi-bin/man/man2html">Return to Main Contents</A><HR>
| |
| | |
| | |
| -----------------------------------------------------------------------
| |
| | |
| | |
| | |
| | |
| <A NAME="lbAB"> </A>
| |
| <H3>NAME</H3>
| |
| | |
| Template::Tutorial::Web - Generating Web Content Using the Template Toolkit
| |
| <A NAME="lbAC"> </A>
| |
| <H3>Overview</H3>
| |
| | |
| <A NAME="ixAAC"></A>
| |
| This tutorial document provides a introduction to the Template Toolkit and
| |
| demonstrates some of the typical ways it may be used for generating web
| |
| content. It covers the generation of static pages from templates using the
| |
| tpage and ttree scripts
| |
| and then goes on to show dynamic content generation using <FONT SIZE="-1">CGI</FONT> scripts and
| |
| Apache/mod_perl handlers.
| |
| <P>
| |
| | |
| Various features of the Template Toolkit are introduced and described briefly
| |
| and explained by use of example. For further information, see Template,
| |
| Template::Manual and the various sections within it. e.g
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| perldoc Template # Template.pm module usage
| |
| perldoc Template::Manual # index to manual
| |
| perldoc Template::Manual::Config # e.g. configuration options
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The documentation is also available in <FONT SIZE="-1">HTML</FONT> format to read online, or download
| |
| from the Template Toolkit web site:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| <A HREF="http://template-toolkit.org/docs/">http://template-toolkit.org/docs/</A>
| |
| | |
| </PRE>
| |
| | |
| | |
| <A NAME="lbAD"> </A>
| |
| <H3>Introduction</H3>
| |
| | |
| <A NAME="ixAAD"></A>
| |
| The Template Toolkit is a set of Perl modules which collectively
| |
| implement a template processing system.
| |
| <P>
| |
| | |
| A template is a text document with special markup tags embedded in it.
| |
| By default, the Template Toolkit uses '<TT>"[%"</TT>' and '<TT>"%]"</TT>' to denote
| |
| the start and end of a tag. Here's an example:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header %]
| |
|
| |
| People of [% planet %], your attention please.
| |
|
| |
| This is [% captain %] of the
| |
| Galactic Hyperspace Planning Council.
| |
|
| |
| As you will no doubt be aware, the plans
| |
| for development of the outlying regions
| |
| of the Galaxy require the building of a
| |
| hyperspatial express route through your
| |
| star system, and regrettably your planet
| |
| is one of those scheduled for destruction.
| |
|
| |
| The process will take slightly less than
| |
| [% time %].
| |
|
| |
| Thank you.
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Tags can contain simple <I>variables</I> (like <TT>"planet"</TT> and <TT>"captain"</TT>) and more
| |
| complex <I>directives</I> that start with an upper case keyword (like <TT>"INCLUDE"</TT>).
| |
| A directive is an instruction that tells the template processor to perform
| |
| some action, like processing another template (<TT>"header"</TT> and <TT>"footer"</TT> in this
| |
| example) and inserting the output into the current template. In fact, the
| |
| simple variables we mentioned are actually <TT>"GET"</TT> directives, but the <TT>"GET"</TT>
| |
| keyword is optional.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| People of [% planet %], your attention please. # short form
| |
| People of [% GET planet %], your attention please. # long form
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Other directives include <TT>"SET"</TT> to set a variable value (the <TT>"SET"</TT> keyword is
| |
| also optional), <TT>"FOREACH"</TT> to iterate through a list of values, and <TT>"IF"</TT>,
| |
| <TT>"UNLESS"</TT>, <TT>"ELSIF"</TT> and <TT>"ELSE"</TT> to declare conditional blocks.
| |
| <P>
| |
| | |
| The Template Toolkit processes all <I>text</I> files equally, regardless of what
| |
| kind of content they contain. So you can use <FONT SIZE="-1">TT</FONT> to generate <FONT SIZE="-1">HTML</FONT>, <FONT SIZE="-1">XML</FONT>, <FONT SIZE="-1">CSS</FONT>,
| |
| Javascript, Perl, <FONT SIZE="-1">RTF</FONT>, LaTeX, or any other text-based format. In this tutorial,
| |
| however, we'll be concentrating on generating <FONT SIZE="-1">HTML</FONT> for web pages.
| |
| <A NAME="lbAE"> </A>
| |
| <H2>Generating Static Web Content</H2>
| |
| | |
| <A NAME="ixAAE"></A>
| |
| Here's an example of a template used to generate an <FONT SIZE="-1">HTML</FONT> document.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header
| |
| title = 'This is an HTML example';
| |
|
| |
| pages = [
| |
| { url = '<A HREF="http://foo.org'">http://foo.org'</A>
| |
| title = 'The Foo Organisation'
| |
| }
| |
| { url = '<A HREF="http://bar.org'">http://bar.org'</A>
| |
| title = 'The Bar Organisation'
| |
| }
| |
| ]
| |
| %]
| |
| <h1>Some Interesting Links</h1>
| |
| <ul>
| |
| [% FOREACH page IN pages %]
| |
| <li><a href="[% page.url %]">[% page.title %]</a>
| |
| [% END %]
| |
| </ul>
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| This example shows how the <TT>"INCLUDE"</TT> directive is used to load and process
| |
| separate '<TT>"header"</TT>' and '<TT>"footer"</TT>' template files, including the output in
| |
| the current document. These files might look something like this:
| |
| <P>
| |
| | |
| header:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| <html>
| |
| <head>
| |
| <title>[% title %]</title>
| |
| </head>
| |
| <body>
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| footer:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| <div class="copyright">
| |
| &copy; Copyright 2007 Arthur Dent
| |
| </div>
| |
| </body>
| |
| </html>
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The example also uses the <TT>"FOREACH"</TT> directive to iterate through the
| |
| '<TT>"pages"</TT>' list to build a table of links. In this example, we have defined
| |
| this list within the template to contain a number of hash references, each
| |
| containing a '<TT>"url"</TT>' and '<TT>"title"</TT>' member. The <TT>"FOREACH"</TT> directive iterates
| |
| through the list, aliasing '<TT>"page"</TT>' to each item (in this case, hash array
| |
| references). The <TT>"[% page.url %]"</TT> and <TT>"[% page.title %]"</TT> directives then
| |
| access the individual values in the hash arrays and insert them into the
| |
| document.
| |
| <A NAME="lbAF"> </A>
| |
| <H4>Using tpage</H4>
| |
| | |
| <A NAME="ixAAF"></A>
| |
| Having created a template file we can now process it to generate some real
| |
| output. The quickest and easiest way to do this is to use the
| |
| tpage script. This is provided as part of the
| |
| Template Toolkit and should be installed in your usual Perl bin directory.
| |
| <P>
| |
| | |
| Assuming you saved your template file as <I>example.html</I>, you would run
| |
| the command:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| $ tpage example.html
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| This will process the template file, sending the output to <TT>"STDOUT"</TT> (i.e.
| |
| whizzing past you on the screen). You may want to redirect the output to a
| |
| file but be careful not to specify the same name as the template file, or
| |
| you'll overwrite it. You may want to use one prefix for your templates (e.g.
| |
| '<TT>".tt"</TT>') and another (e.g. '<TT>".html"</TT>') for the output files.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| $ tpage example.tt > example.html
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Or you can redirect the output to another directory. e.g.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| $ tpage templates/example.tt > html/example.html
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The output generated would look like this:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| <html>
| |
| <head>
| |
| <title>This is an HTML example</title>
| |
| </head>
| |
| <body>
| |
| <h1>Some Interesting Links</h1>
| |
| <ul>
| |
| <li><a href="<A HREF="http://foo.org">http://foo.org</A>">The Foo Organsiation</a>
| |
| <li><a href="<A HREF="http://bar.org">http://bar.org</A>">The Bar Organsiation</a>
| |
| </ul>
| |
| <div class="copyright">
| |
| &copy; Copyright 2007 Arthur Dent
| |
| </div>
| |
| </body>
| |
| </html>
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The <I>header</I> and <I>footer</I> template files have been included (assuming
| |
| you created them and they're in the current directory) and the link data
| |
| has been built into an <FONT SIZE="-1">HTML</FONT> list.
| |
| <A NAME="lbAG"> </A>
| |
| <H4>Using ttree</H4>
| |
| | |
| <A NAME="ixAAG"></A>
| |
| The tpage script gives you a simple and easy way to
| |
| process a single template without having to write any Perl code. The
| |
| <ttree:Template::Tools::ttree> script, also distributed as part of the
| |
| Template Toolkit, provides a more flexible way to process a number of template
| |
| documents in one go.
| |
| <P>
| |
| | |
| The first time you run the script, it will ask you if it should create a
| |
| configuration file (<I>.ttreerc</I>) in your home directory. Answer <TT>"y"</TT> to have
| |
| it create the file.
| |
| <P>
| |
| | |
| The <ttree:Template::Tools::ttree> documentation describes how you can change
| |
| the location of this file and also explains the syntax and meaning of the
| |
| various options in the file. Comments are written to the sample configuration
| |
| file which should also help.
| |
| <P>
| |
| | |
| In brief, the configuration file describes the directories in which template
| |
| files are to be found (<TT>"src"</TT>), where the corresponding output should be
| |
| written to (<TT>"dest"</TT>), and any other directories (<TT>"lib"</TT>) that may contain
| |
| template files that you plan to <TT>"INCLUDE"</TT> into your source documents. You can
| |
| also specify processing options (such as <TT>"verbose"</TT> and <TT>"recurse"</TT>) and provide
| |
| regular expression to match files that you don't want to process (<TT>"ignore"</TT>,
| |
| <TT>"accept"</TT>)> or should be copied instead of being processed as templates (<TT>"copy"</TT>).
| |
| <P>
| |
| | |
| An example <I>.ttreerc</I> file is shown here:
| |
| <P>
| |
| | |
| <TT>$HOME</TT>/.ttreerc:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| verbose
| |
| recurse
| |
|
| |
| # this is where I keep other ttree config files
| |
| cfg = ~/.ttree
| |
|
| |
| src = ~/websrc/src
| |
| lib = ~/websrc/lib
| |
| dest = ~/public_html/test
| |
|
| |
| ignore = \b(CVS|RCS)\b
| |
| ignore = ^#
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| You can create many different configuration files and store them
| |
| in the directory specified in the <TT>"cfg"</TT> option, shown above. You then
| |
| add the <TT>"-f filename"</TT> option to <TT>"ttree"</TT> to have it read that file.
| |
| <P>
| |
| | |
| When you run the script, it compares all the files in the <TT>"src"</TT> directory
| |
| (including those in sub-directories if the <TT>"recurse"</TT> option is set), with
| |
| those in the <TT>"dest"</TT> directory. If the destination file doesn't exist or
| |
| has an earlier modification time than the corresponding source file, then
| |
| the source will be processed with the output written to the destination
| |
| file. The <TT>"-a"</TT> option forces all files to be processed, regardless of
| |
| modification times.
| |
| <P>
| |
| | |
| The script <I>doesn't</I> process any of the files in the <TT>"lib"</TT> directory, but it
| |
| does add it to the <TT>"INCLUDE_PATH"</TT> for the template processor so that it can
| |
| locate these files via an <TT>"INCLUDE"</TT>, <TT>"PROCESS"</TT> or <TT>"WRAPPER"</TT> directive.
| |
| Thus, the <TT>"lib"</TT> directory is an excellent place to keep template elements
| |
| such as header, footers, etc., that aren't complete documents in their own
| |
| right.
| |
| <P>
| |
| | |
| You can also specify various Template Toolkit options from the configuration
| |
| file. Consult the ttree documentation and help
| |
| summary (<TT>"ttree -h"</TT>) for full details. e.g.
| |
| <P>
| |
| | |
| <TT>$HOME</TT>/.ttreerc:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| pre_process = config
| |
| interpolate
| |
| post_chomp
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The <TT>"pre_process"</TT> option allows you to specify a template file which
| |
| should be processed before each file. Unsurprisingly, there's also a
| |
| <TT>"post_process"</TT> option to add a template after each file. In the
| |
| fragment above, we have specified that the <TT>"config"</TT> template should be
| |
| used as a prefix template. We can create this file in the <TT>"lib"</TT>
| |
| directory and use it to define some common variables, including those
| |
| web page links we defined earlier and might want to re-use in other
| |
| templates. We could also include an <FONT SIZE="-1">HTML</FONT> header, title, or menu bar
| |
| in this file which would then be prepended to each and every template
| |
| file, but for now we'll keep all that in a separate <TT>"header"</TT> file.
| |
| <P>
| |
| | |
| <TT>$lib</TT>/config:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% root = '~/abw'
| |
| home = "$root/index.html"
| |
| images = "$root/images"
| |
| email = '<A HREF="mailto:abw@wardley.org">abw@wardley.org</A>'
| |
| graphics = 1
| |
| webpages = [
| |
| { url => '<A HREF="http://foo.org',">http://foo.org',</A> title => 'The Foo Organsiation' }
| |
| { url => '<A HREF="http://bar.org',">http://bar.org',</A> title => 'The Bar Organsiation' }
| |
| ]
| |
| %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Assuming you've created or copied the <TT>"header"</TT> and <TT>"footer"</TT> files from the
| |
| earlier example into your <TT>"lib"</TT> directory, you can now start to create
| |
| web pages like the following in your <TT>"src"</TT> directory and process them
| |
| with <TT>"ttree"</TT>.
| |
| <P>
| |
| | |
| <TT>$src</TT>/newpage.html:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header
| |
| title = 'Another Template Toolkit Test Page'
| |
| %]
| |
|
| |
| <a href="[% home %]">Home</a>
| |
| <a href="mailto:[% email %]">Email</a>
| |
|
| |
| [% IF graphics %]
| |
| <img src="[% images %]/logo.gif" align=right width=60 height=40>
| |
| [% END %]
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Here we've shown how pre-defined variables can be used as flags to
| |
| enable certain feature (e.g. <TT>"graphics"</TT>) and to specify common items
| |
| such as an email address and <FONT SIZE="-1">URL</FONT>'s for the home page, images directory
| |
| and so on. This approach allows you to define these values once so
| |
| that they're consistent across all pages and can easily be changed to
| |
| new values.
| |
| <P>
| |
| | |
| When you run <I>ttree</I>, you should see output similar to the following
| |
| (assuming you have the verbose flag set).
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| ttree 2.9 (Template Toolkit version 2.20)
| |
|
| |
| Source: /home/abw/websrc/src
| |
| Destination: /home/abw/public_html/test
| |
| Include Path: [ /home/abw/websrc/lib ]
| |
| Ignore: [ \b(CVS|RCS)\b, ^# ]
| |
| Copy: [ ]
| |
| Accept: [ * ]
| |
|
| |
| + newpage.html
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The <TT>"+"</TT> in front of the <TT>"newpage.html"</TT> filename shows that the file was
| |
| processed, with the output being written to the destination directory. If you
| |
| run the same command again, you'll see the following line displayed instead
| |
| showing a <TT>"-"</TT> and giving a reason why the file wasn't processed.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| - newpage.html (not modified)
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| It has detected a <TT>"newpage.html"</TT> in the destination directory which is
| |
| more recent than that in the source directory and so hasn't bothered
| |
| to waste time re-processing it. To force all files to be processed,
| |
| use the <TT>"-a"</TT> option. You can also specify one or more filenames as
| |
| command line arguments to <TT>"ttree"</TT>:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| tpage newpage.html
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| This is what the destination page looks like.
| |
| <P>
| |
| | |
| <TT>$dest</TT>/newpage.html:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| <html>
| |
| <head>
| |
| <title>Another Template Toolkit Test Page</title>
| |
| </head>
| |
| <body>
| |
|
| |
| <a href="~/abw/index.html">Home</a>
| |
| <a href="mailto:<A HREF="mailto:abw@wardley.org">abw@wardley.org</A>">Email me</a>
| |
| <img src="~/abw/images/logo.gif" align=right width=60 height=40>
| |
|
| |
| <div class="copyright">
| |
| &copy; Copyright 2007 Arthur Dent
| |
| </div>
| |
| </body>
| |
| </html>
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| You can add as many documents as you like to the <TT>"src"</TT> directory and
| |
| <TT>"ttree"</TT> will apply the same process to them all. In this way, it is
| |
| possible to build an entire tree of static content for a web site with
| |
| a single command. The added benefit is that you can be assured of
| |
| consistency in links, header style, or whatever else you choose to
| |
| implement in terms of common templates elements or variables.
| |
| <A NAME="lbAH"> </A>
| |
| <H3>Dynamic Content Generation Via CGI Script</H3>
| |
| | |
| <A NAME="ixAAH"></A>
| |
| The Template module provides a simple front-end to the Template Toolkit for
| |
| use in <FONT SIZE="-1">CGI</FONT> scripts and Apache/mod_perl handlers. Simply <TT>"use"</TT> the Template
| |
| module, create an object instance with the <I>new()</I> method and then call the
| |
| <I>process()</I> method on the object, passing the name of the template file as a
| |
| parameter. The second parameter passed is a reference to a hash array of
| |
| variables that we want made available to the template:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| #!/usr/bin/perl
| |
| use strict;
| |
| use warnings;
| |
| use Template;
| |
|
| |
| my $file = 'src/greeting.html';
| |
| my $vars = {
| |
| message => "Hello World\n"
| |
| };
| |
|
| |
| my $template = Template->new();
| |
|
| |
| $template->process($file, $vars)
| |
| || die "Template process failed: ", $template->error(), "\n";
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| So that our scripts will work with the same template files as our earlier
| |
| examples, we'll can add some configuration options to the constructor to
| |
| tell it about our environment:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| my $template->new({
| |
| # where to find template files
| |
| INCLUDE_PATH => ['/home/abw/websrc/src', '/home/abw/websrc/lib'],
| |
| # pre-process lib/config to define any extra values
| |
| PRE_PROCESS => 'config',
| |
| });
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Note that here we specify the <TT>"config"</TT> file as a <TT>"PRE_PROCESS"</TT> option.
| |
| This means that the templates we process can use the same global
| |
| variables defined earlier for our static pages. We don't have to
| |
| replicate their definitions in this script. However, we can supply
| |
| additional data and functionality specific to this script via the hash
| |
| of variables that we pass to the <TT>"process()"</TT> method.
| |
| <P>
| |
| | |
| These entries in this hash may contain simple text or other values,
| |
| references to lists, others hashes, sub-routines or objects. The Template
| |
| Toolkit will automatically apply the correct procedure to access these
| |
| different types when you use the variables in a template.
| |
| <P>
| |
| | |
| Here's a more detailed example to look over. Amongst the different
| |
| template variables we define in <TT>$vars</TT>, we create a reference to a
| |
| <FONT SIZE="-1">CGI</FONT> object and a <TT>"get_user_projects()"</TT> sub-routine.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| #!/usr/bin/perl
| |
| use strict;
| |
| use warnings;
| |
| use Template;
| |
| use CGI;
| |
|
| |
| $| = 1;
| |
| print "Content-type: text/html\n\n";
| |
|
| |
| my $file = 'userinfo.html';
| |
| my $vars = {
| |
| 'version' => 3.14,
| |
| 'days' => [ qw( mon tue wed thu fri sat sun ) ],
| |
| 'worklist' => \&get_user_projects,
| |
| 'cgi' => CGI->new(),
| |
| 'me' => {
| |
| 'id' => 'abw',
| |
| 'name' => 'Andy Wardley',
| |
| },
| |
| };
| |
|
| |
| sub get_user_projects {
| |
| my $user = shift;
| |
| my @projects = ... # do something to retrieve data
| |
| return \@projects;
| |
| }
| |
|
| |
| my $template = Template->new({
| |
| INCLUDE_PATH => '/home/abw/websrc/src:/home/abw/websrc/lib',
| |
| PRE_PROCESS => 'config',
| |
| });
| |
|
| |
| $template->process($file, $vars)
| |
| || die $template->error();
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Here's a sample template file that we might create to build the output
| |
| for this script.
| |
| <P>
| |
| | |
| <TT>$src</TT>/userinfo.html:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header
| |
| title = 'Template Toolkit CGI Test'
| |
| %]
| |
|
| |
| <a href="mailto:[% email %]">Email [% me.name %]</a>
| |
|
| |
| <p>This is version [% version %]</p>
| |
|
| |
| <h3>Projects</h3>
| |
| <ul>
| |
| [% FOREACH project IN worklist(me.id) %]
| |
| <li> <a href="[% project.url %]">[% project.name %]</a>
| |
| [% END %]
| |
| </ul>
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| This example shows how we've separated the Perl implementation (code) from the
| |
| presentation (<FONT SIZE="-1">HTML</FONT>). This not only makes them easier to maintain in isolation,
| |
| but also allows the re-use of existing template elements such as headers and
| |
| footers, etc. By using template to create the output of your <FONT SIZE="-1">CGI</FONT> scripts, you
| |
| can give them the same consistency as your static pages built via
| |
| ttree or other means.
| |
| <P>
| |
| | |
| Furthermore, we can modify our script so that it processes any one of a
| |
| number of different templates based on some condition. A <FONT SIZE="-1">CGI</FONT> script to
| |
| maintain a user database, for example, might process one template to
| |
| provide an empty form for new users, the same form with some default
| |
| values set for updating an existing user record, a third template for
| |
| listing all users in the system, and so on. You can use any Perl
| |
| functionality you care to write to implement the logic of your
| |
| application and then choose one or other template to generate the
| |
| desired output for the application state.
| |
| <A NAME="lbAI"> </A>
| |
| <H3>Dynamic Content Generation Via Apache/Mod_Perl Handler</H3>
| |
| | |
| <A NAME="ixAAI"></A>
| |
| <B></B><FONT SIZE="-1"><B>NOTE:</B></FONT><B></B> the Apache::Template module is available from <FONT SIZE="-1">CPAN</FONT> and provides a
| |
| simple and easy to use Apache/mod_perl interface to the Template Toolkit.
| |
| Although basic, it implements most, if not all of what is described below, and
| |
| it avoids the need to write your own handler. However, in many cases, you'll
| |
| want to write your own handler to customise processing for your own need, and
| |
| this section will show you how to get started.
| |
| <P>
| |
| | |
| The Template module can be used from an Apache/mod_perl handler. Here's an
| |
| example of a typical Apache <I>httpd.conf</I> file:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| PerlModule CGI;
| |
| PerlModule Template
| |
| PerlModule MyOrg::Apache::User
| |
|
| |
| PerlSetVar websrc_root /home/abw/websrc
| |
|
| |
| <Location /user/bin>
| |
| SetHandler perl-script
| |
| PerlHandler MyOrg::Apache::User
| |
| </Location>
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| This defines a location called <TT>"/user/bin"</TT> to which all requests will
| |
| be forwarded to the <TT>"handler()"</TT> method of the <TT>"MyOrg::Apache::User"</TT>
| |
| module. That module might look something like this:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| package MyOrg::Apache::User;
| |
|
| |
| use strict;
| |
| use vars qw( $VERSION );
| |
| use Apache::Constants qw( :common );
| |
| use Template qw( :template );
| |
| use CGI;
| |
|
| |
| $VERSION = 1.59;
| |
|
| |
| sub handler {
| |
| my $r = shift;
| |
|
| |
| my $websrc = $r->dir_config('websrc_root')
| |
| or return fail($r, SERVER_ERROR,
| |
| "'websrc_root' not specified");
| |
|
| |
| my $template = Template->new({
| |
| INCLUDE_PATH => "$websrc/src/user:$websrc/lib",
| |
| PRE_PROCESS => 'config',
| |
| OUTPUT => $r, # direct output to Apache request
| |
| });
| |
|
| |
| my $params = {
| |
| uri => $r->uri,
| |
| cgi => CGI->new,
| |
| };
| |
|
| |
| # use the path_info to determine which template file to process
| |
| my $file = $r->path_info;
| |
| $file =~ s[^/][];
| |
|
| |
| $r->content_type('text/html');
| |
| $r->send_http_header;
| |
|
| |
| $template->process($file, $params)
| |
| || return fail($r, SERVER_ERROR, $template->error());
| |
|
| |
| return OK;
| |
| }
| |
|
| |
| sub fail {
| |
| my ($r, $status, $message) = @_;
| |
| $r->log_reason($message, $r->filename);
| |
| return $status;
| |
| }
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The handler accepts the request and uses it to determine the <TT>"websrc_root"</TT>
| |
| value from the config file. This is then used to define an <TT>"INCLUDE_PATH"</TT>
| |
| for a new Template object. The <FONT SIZE="-1">URI</FONT> is extracted from the request and a
| |
| <FONT SIZE="-1">CGI</FONT> object is created. These are both defined as template variables.
| |
| <P>
| |
| | |
| The name of the template file itself is taken from the <TT>"PATH_INFO"</TT> element
| |
| of the request. In this case, it would comprise the part of the <FONT SIZE="-1">URL</FONT>
| |
| coming after <TT>"/user/bin"</TT>, e.g for <TT>"/user/bin/edit"</TT>, the template file
| |
| would be <TT>"edit"</TT> located in <TT>"$websrc/src/user"</TT>. The headers are sent
| |
| and the template file is processed. All output is sent directly to the
| |
| <TT>"print()"</TT> method of the Apache request object.
| |
| <A NAME="lbAJ"> </A>
| |
| <H3>Using Plugins to Extend Functionality</H3>
| |
| | |
| <A NAME="ixAAJ"></A>
| |
| As we've already shown, it is possible to bind Perl data and functions
| |
| to template variables when creating dynamic content via a <FONT SIZE="-1">CGI</FONT> script
| |
| or Apache/mod_perl process. The Template Toolkit also supports a
| |
| plugin interface which allows you define such additional data and/or
| |
| functionality in a separate module and then load and use it as
| |
| required with the <TT>"USE"</TT> directive.
| |
| <P>
| |
| | |
| The main benefit to this approach is that you can load the extension into
| |
| any template document, even those that are processed ``statically'' by
| |
| <TT>"tpage"</TT> or <TT>"ttree"</TT>. You <I>don't</I> need to write a Perl wrapper to
| |
| explicitly load the module and make it available via the stash.
| |
| <P>
| |
| | |
| Let's demonstrate this principle using the <TT>"DBI"</TT> plugin written by Simon
| |
| Matthews (available from <FONT SIZE="-1">CPAN</FONT>). You can create this template in your <TT>"src"</TT>
| |
| directory and process it using <TT>"ttree"</TT> to see the results. Of course, this
| |
| example relies on the existence of the appropriate <FONT SIZE="-1">SQL</FONT> database but you should
| |
| be able to adapt it to your own resources, or at least use it as a
| |
| demonstrative example of what's possible.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header
| |
| title = 'User Info'
| |
| %]
| |
|
| |
| [% USE DBI('dbi:mSQL:mydbname') %]
| |
|
| |
| <table border=0 width="100%">
| |
| <tr>
| |
| <th>User ID</th>
| |
| <th>Name</th>
| |
| <th>Email</th>
| |
| </tr>
| |
| [% FOREACH user IN DBI.query('SELECT * FROM user ORDER BY id') %]
| |
| <tr>
| |
| <td>[% user.id %]</td>
| |
| <td>[% user.name %]</td>
| |
| <td>[% user.email %]</td>
| |
| </tr>
| |
| [% END %]
| |
| </table>
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| A plugin is simply a Perl module in a known location and conforming to
| |
| a known standard such that the Template Toolkit can find and load it
| |
| automatically. You can create your own plugin by inheriting from the
| |
| Template::Plugin module.
| |
| <P>
| |
| | |
| Here's an example which defines some data items (<TT>"foo"</TT> and <TT>"people"</TT>)
| |
| and also an object method (<TT>"bar"</TT>). We'll call the plugin <TT>"FooBar"</TT> for
| |
| want of a better name and create it in the <TT>"MyOrg::Template::Plugin::FooBar"</TT>
| |
| package. We've added a <TT>"MyOrg"</TT> to the regular <TT>"Template::Plugin::*"</TT> package
| |
| to avoid any conflict with existing plugins.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| package MyOrg::Template::Plugin::FooBar;
| |
| use base 'Template::Plugin'
| |
| our $VERSION = 1.23;
| |
|
| |
| sub new {
| |
| my ($class, $context, @params) = @_;
| |
|
| |
| bless {
| |
| _CONTEXT => $context,
| |
| foo => 25,
| |
| people => [ 'tom', 'dick', 'harry' ],
| |
| }, $class;
| |
| }
| |
|
| |
| sub bar {
| |
| my ($self, @params) = @_;
| |
| # ...do something...
| |
| return $some_value;
| |
| }
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The plugin constructor <TT>"new()"</TT> receives the class name as the first
| |
| parameter, as is usual in Perl, followed by a reference to something called a
| |
| Template::Context object. You don't need to worry too much about this at
| |
| the moment, other than to know that it's the main processing object for the
| |
| Template Toolkit. It provides access to the functionality of the processor and
| |
| some plugins may need to communicate with it. We don't at this stage, but
| |
| we'll save the reference anyway in the <TT>"_CONTEXT"</TT> member. The leading
| |
| underscore is a convention which indicates that this item is private and the
| |
| Template Toolkit won't attempt to access this member. The other members
| |
| defined, <TT>"foo"</TT> and <TT>"people"</TT> are regular data items which will be made
| |
| available to templates using this plugin. Following the context reference are
| |
| passed any additional parameters specified with the <FONT SIZE="-1">USE</FONT> directive, such as the
| |
| data source parameter, <TT>"dbi:mSQL:mydbname"</TT>, that we used in the earlier <FONT SIZE="-1">DBI</FONT>
| |
| example.
| |
| <P>
| |
| | |
| If you don't or can't install it to the regular place for your Perl
| |
| modules (perhaps because you don't have the required privileges) then
| |
| you can set the <FONT SIZE="-1">PERL5LIB</FONT> environment variable to specify another location.
| |
| If you're using <TT>"ttree"</TT> then you can add the following line to your
| |
| configuration file instead.
| |
| <P>
| |
| | |
| <TT>$HOME</TT>/.ttreerc:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| perl5lib = /path/to/modules
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| One further configuration item must be added to inform the toolkit of
| |
| the new package name we have adopted for our plugins:
| |
| <P>
| |
| | |
| <TT>$HOME</TT>/.ttreerc:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| plugin_base = 'MyOrg::Template::Plugin'
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| If you're writing Perl code to control the Template modules directly,
| |
| then this value can be passed as a configuration parameter when you
| |
| create the module.
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| use Template;
| |
|
| |
| my $template = Template->new({
| |
| PLUGIN_BASE => 'MyOrg::Template::Plugin'
| |
| });
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| Now we can create a template which uses this plugin:
| |
| <P>
| |
| | |
| | |
| | |
| <PRE>
| |
| [% INCLUDE header
| |
| title = 'FooBar Plugin Test'
| |
| %]
| |
|
| |
| [% USE FooBar %]
| |
|
| |
| Some values available from this plugin:
| |
| [% FooBar.foo %] [% FooBar.bar %]
| |
|
| |
| The users defined in the 'people' list:
| |
| [% FOREACH uid = FooBar.people %]
| |
| * [% uid %]
| |
| [% END %]
| |
|
| |
| [% INCLUDE footer %]
| |
| | |
| </PRE>
| |
| | |
| | |
| <P>
| |
| | |
| The <TT>"foo"</TT>, <TT>"bar"</TT>, and <TT>"people"</TT> items of the FooBar plugin are
| |
| automatically resolved to the appropriate data items or method calls
| |
| on the underlying object.
| |
| <P>
| |
| | |
| Using this approach, it is possible to create application
| |
| functionality in a single module which can then be loaded and used on
| |
| demand in any template. The simple interface between template
| |
| directives and plugin objects allows complex, dynamic content to be
| |
| built from a few simple template documents without knowing anything
| |
| about the underlying implementation.
| |
| <A NAME="lbAK"> </A>
| |
| <H3>AUTHOR</H3>
| |
| | |
| <A NAME="ixAAK"></A>
| |
| Andy Wardley <<A HREF="mailto:abw@wardley.org">abw@wardley.org</A>> <<A HREF="http://wardley.org/">http://wardley.org/</A>>
| |
| <A NAME="lbAL"> </A>
| |
| <H3>COPYRIGHT</H3>
| |
| | |
| <A NAME="ixAAL"></A>
| |
| Copyright (C) 1996-2007 Andy Wardley. All Rights Reserved.
| |
| <P>
| |
| | |
| This module is free software; you can redistribute it and/or
| |
| modify it under the same terms as Perl itself.
| |
| <P>
| |
| | |
| <HR>
| |
| <A NAME="index"> </A><H2>Index</H2>
| |
| <DL>
| |
| <DT><A HREF="#lbAB">NAME</A><DD>
| |
| <DT><A HREF="#lbAC">Overview</A><DD>
| |
| <DT><A HREF="#lbAD">Introduction</A><DD>
| |
| <DT><A HREF="#lbAE">Generating Static Web Content</A><DD>
| |
| <DL>
| |
| <DT><A HREF="#lbAF">Using tpage</A><DD>
| |
| <DT><A HREF="#lbAG">Using ttree</A><DD>
| |
| </DL>
| |
| <DT><A HREF="#lbAH">Dynamic Content Generation Via CGI Script</A><DD>
| |
| <DT><A HREF="#lbAI">Dynamic Content Generation Via Apache/Mod_Perl Handler</A><DD>
| |
| <DT><A HREF="#lbAJ">Using Plugins to Extend Functionality</A><DD>
| |
| <DT><A HREF="#lbAK">AUTHOR</A><DD>
| |
| <DT><A HREF="#lbAL">COPYRIGHT</A><DD>
| |
| </DL>
| |