diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
| commit | 3282be229999dc36c197b264d63063a18d136331 (patch) | |
| tree | 98a42db29d955b39e7bed1b599fdcc56c3a29de9 /lib/Template/Tutorial | |
| parent | cfdd733c17cfa4f1a43b827a656e9e53cc2524ac (diff) | |
| download | xxv-3282be229999dc36c197b264d63063a18d136331.tar.gz xxv-3282be229999dc36c197b264d63063a18d136331.tar.bz2 | |
* Update installation list with required modules
* Remove unused/doubled provided external perl moduls
Diffstat (limited to 'lib/Template/Tutorial')
| -rw-r--r-- | lib/Template/Tutorial/Datafile.pod | 461 | ||||
| -rw-r--r-- | lib/Template/Tutorial/Web.pod | 801 |
2 files changed, 0 insertions, 1262 deletions
diff --git a/lib/Template/Tutorial/Datafile.pod b/lib/Template/Tutorial/Datafile.pod deleted file mode 100644 index 652f79d..0000000 --- a/lib/Template/Tutorial/Datafile.pod +++ /dev/null @@ -1,461 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Tutorial::Datafile -# -# DESCRIPTION -# This tutorial gives an overview of the Template Toolkit, showing in -# particular how to use it to read and write data files in various -# different formats and styles. It was written by Dave Cross and -# first appeared as a lead article at http://www.perl.com/ earlier in -# the year (2001). -# -# AUTHOR -# Dave Cross <dave@dave.org.uk> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 Canon Research Centre Europe Ltd. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tutorial::Datafile - Creating Data Output Files Using the Template Toolkit - -=head1 DESCRIPTION - -This tutorial gives an overview of the Template Toolkit, showing in -particular how to use it to read and write data files in various -different formats and styles. It was written by Dave Cross and first -appeared as a lead article at http://www.perl.com/ earlier in the year -(2001). - -=head1 Introducing the Template Toolkit - -There are a number of Perl modules that are universally -recognised as The Right Thing To Use for certain tasks. If you -accessed a database without using DBI, pulled data from the WWW -without using one of the LWP modules or parsed XML without using -XML::Parser or one of its subclasses then you'd run the risk of -being shunned by polite Perl society. - -I believe that the year 2000 saw the emergence of another 'must -have' Perl module - the Template Toolkit. I don't think I'm -alone in this belief as the Template Toolkit won the 'Best New -Module' award at the Perl Conference last summer. Version 2.0 of -the Template Toolkit (known as TT2 to its friends) was recently -released to the CPAN. - -TT2 was designed and written by Andy Wardley E<lt>abw@wardley.orgE<gt>. -It was born out of Andy's previous templating module, -Text::Metatext, in best Fred Brooks 'plan to throw one away' -manner; and aims to be the most useful (or, at least, the most -I<used>) Perl templating system. - -TT2 provides a way to take a file of fixed boilerplate text -(the template) and embed variable data within it. One obvious -use of this is in the creation of dynamic web pages and this is -where a lot of the attention that TT2 has received has been -focussed. In this article, I hope to demonstrate that TT2 is -just as useful in non-web applications. - -=head1 Using the Template Toolkit - -Let's look at how we'd use TT2 to process a simple data file. -TT2 is an object oriented Perl module. Having downloaded it from -CPAN and installed it in the usual manner, using it in your -program is as easy as putting the lines - - use Template; - my $tt = Template->new; - -in your code. The constructor function, C<new>, takes -a number of optional parameters which are documented in the -copious manual pages that come with the module, but for the -purposes of this article we'll keep things as simple as -possible. - -To process the template, you would call the C<process> method -like this - - $tt->process('my_template', \%data) - || die $tt->error; - -We pass two parameters to C<process>, the first is the name of -the file containing the template to process (in this case, -my_template) and the second is a reference to a hash which -contains the data items that you want to use in the template. If -processing the template gives any kind of error, the program -will die with a (hopefully) useful error message. - -So what kinds of things can go in C<%data>? The answer is just -about anything. Here's an example showing data about English -Premier League football teams. - - my @teams = ({ name => 'Man Utd', - played => 16, - won => 12, - drawn => 3, - lost => 1 }, - { name => 'Bradford', - played => 16, - won => 2, - drawn => 5, - lost => 9 }); - - my %data = ( name => 'English Premier League', - season => '2000/01', - teams => \@teams ); - -This creates three data items which can be accessed within the -template, called C<name>, C<season> and C<teams>. Notice that -C<teams> is a complex data structure. - -Here is a template that we might use to process this data. - - League Standings - - League Name: [% name %] - Season : [% season %] - - Teams: - [% FOREACH team = teams -%] - [% team.name %] [% team.played -%] - [% team.won %] [% team.drawn %] [% team.lost %] - [% END %] - -Running this template with this data gives us the following -output - - League Standings - - League Name: English Premier League - Season : 2000/01 - - Teams: - Man Utd 16 12 3 1 - Bradford 16 2 5 9 - -Hopefully the syntax of the template is simple enough to -follow. There are a few points to note. - -=over 4 - -=item * - -Template processing directives are written using a simple -language which is not Perl. - -=item * - -The keys of the C<%data> have become the names of the data -variables within the template. - -=item * - -Template processing directives are surrounded by C<[%> and -C<%]> sequences. - -=item * - -If these tags are replaced with C<[%-> C<-%]> then the preceding -or following linefeed is suppressed. - -=item * - -In the C<FOREACH> loop, each element of the C<teams> list was -assigned, in turn, to the temporary variable C<team>. - -=item * - -Each item assigned to the C<team> variable is a Perl hash. -Individual values within the hash are accessed using a dot notation. - -=back - -It's probably the first and last of these points which are the -most important. The first point emphasises the separation of the -data acquisition logic from the presentation logic. The person -creating the presentation template doesn't need to know Perl, -they only need to know the data items which will be passed into -the template. - -The last point demonstrates the way that TT2 protects the -template designer from the implementation of the data structures. -The data objects passed to the template processor can be scalars, -arrays, hashes, objects or even subroutines. The template -processor will just interpret your data correctly and Do The -Right Thing to return the correct value to you. In this example -each team was a hash, but in a larger system each team might be -an object, in which case C<name>, C<played>, etc. would be accessor -methods to the underlying object attributes. No changes would be -required to the template as the template processor would realise -that it needed to call methods rather than access hash values. - -=head2 A more complex example - -Stats about the English Football League are usually presented in -a slightly more complex format than the one we used above. A -full set of stats will show the number of games that a team has -won, lost or drawn, the number of goals scored for and against -the team and the number of points that the team therefore has. -Teams gain three points for a win and one point for a draw. When -teams have the same number of points they are separated by the -goal difference, that is the number of goals the team has scored -minus the number of team scored against them. To complicate -things even further, the games won, drawn and lost and the goals -for and against are often split between home and away games. - -Therefore if you have a data source which lists the team name -togther with the games won, drawn and lost and the goals for and -against split into home and away (a total of eleven data items) -you can calculate all of the other items (goal difference, -points awarded and even position in the league). Let's take such -a file, but we'll only look at the top three teams. It will look -something like this: - - Man Utd,7,1,0,26,4,5,2,1,15,6 - Arsenal,7,1,0,17,4,2,3,3,7,9 - Leicester,4,3,1,10,8,4,2,2,7,4 - -A simple script to read this data into an array of hashes will -look something like this (I've simplified the names of the data -columns - w, d, and l are games won, drawn and lost and f and a -are goals scored for and against; h and a at the front of a data -item name indicates whether it's a home or away statistic): - - my @cols = qw(name hw hd hl hf ha aw ad al af aa); - - my @teams; - while (<>) { - chomp; - - my %team; - - @team{@cols} = split /,/; - - push @teams, \%team; - } - -We can then go thru the teams again and calculate all of the -derived data items: - - foreach (@teams) { - $_->{w} = $_->{hw} + $_->{aw}; - $_->{d} = $_->{hd} + $_->{ad}; - $_->{l} = $_->{hl} + $_->{al}; - - $_->{pl} = $_->{w} + $_->{d} + $_->{l}; - - $_->{f} = $_->{hf} + $_->{af}; - $_->{a} = $_->{ha} + $_->{aa}; - - $_->{gd} = $_->{f} - $_->{a}; - $_->{pt} = (3 * $_->{w}) + $_->{d}; - } - -And then produce a list sorted in descending order: - - @teams = sort { - $b->{pt} <=> $b->{pt} || $b->{gd} <=> $a->{gd} - } @teams; - -And finally add the league position data item: - - $teams[$_]->{pos} = $_ + 1 - foreach 0 .. $#teams; - -Having pulled all of our data into an internal data structure -we can start to produce output using out templates. A template -to create a CSV file containing the data split between home and -away stats would look like this: - - [% FOREACH team = teams -%] - [% team.pos %],[% team.name %],[% team.pl %],[% team.hw %], - [%- team.hd %],[% team.hl %],[% team.hf %],[% team.ha %], - [%- team.aw %],[% team.ad %],[% team.al %],[% team.af %], - [%- team.aa %],[% team.gd %],[% team.pt %] - [%- END %] - -And processing it like this: - - $tt->process('split.tt', { teams => \@teams }, 'split.csv') - || die $tt->error; - -produces the following output: - - 1,Man Utd,16,7,1,0,26,4,5,2,1,15,6,31,39 - 2,Arsenal,16,7,1,0,17,4,2,3,3,7,9,11,31 - 3,Leicester,16,4,3,1,10,8,4,2,2,7,4,5,29 - -Notice that we've introduced the third parameter to C<process>. -If this parameter is missing then the TT2 sends its output to -C<STDOUT>. If this parameter is a scalar then it is taken as the -name of a file to write the output to. This parameter can also be -(amongst other things) a filehandle or a reference to an object w -hich is assumed to implement a C<print> method. - -If we weren't interested in the split between home and away games, -then we could use a simpler template like this: - - [% FOREACH team = teams -%] - [% team.pos %],[% team.name %],[% team.pl %],[% team.w %], - [%- team.d %],[% team.l %],[% team.f %],[% team.a %], - [%- team.aa %],[% team.gd %],[% team.pt %] - [% END -%] - -Which would produce output like this: - - 1,Man Utd,16,12,3,1,41,10,6,31,39 - 2,Arsenal,16,9,4,3,24,13,9,11,31 - 3,Leicester,16,8,5,3,17,12,4,5,29 - -=head1 Producing XML - -This is starting to show some of the power and flexibility of -TT2, but you may be thinking that you could just as easily produce -this output with a C<foreach> loop and a couple of C<print> -statements in your code. This is, of course, true; but that's -because I've chosen a deliberately simple example to explain the -concepts. What if we wanted to produce an XML file containing the -data? And what if (as I mentioned earlier) the league data was held -in an object? The code would then look even easier as most of the code -we've written earlier would be hidden away in C<FootballLeague.pm>. - - use FootballLeague; - use Template; - - my $league = FootballLeague->new(name => 'English Premier'); - - my $tt = Template->new; - - $tt->process('league_xml.tt', { league => $league }) - || die $tt->error; - -And the template in C<league_xml.tt> would look something like this: - - <?xml version="1.0"?> - <!DOCTYPE LEAGUE SYSTEM "league.dtd"> - - <league name="[% league.name %]" season="[% league.season %]"> - [% FOREACH team = league.teams -%] - <team name="[% team.name %]" - pos="[% team.pos %]" - played="[% team.pl %]" - goal_diff="[% team.gd %]" - points="[% team.pt %]"> - <stats type="home"> - win="[% team.hw %]" - draw="[%- team.hd %]" - lose="[% team.hl %]" - for="[% team.hf %]" - against="[% team.ha %]" /> - <stats type="away"> - win="[% team.aw %]" - draw="[%- team.ad %]" - lose="[% team.al %]" - for="[% team.af %]" - against="[% team.aa %]" /> - </team> - [% END -%] - &/league> - -Notice that as we've passed the whole object into C<process> then -we need to put an extra level of indirection on our template -variables - everything is now a component of the C<league> variable. -Other than that, everything in the template is very similar to what -we've used before. Presumably now C<team.name> calls an accessor -function rather than carrying out a hash lookup, but all of this -is transparent to our template designer. - -=head1 Multiple Formats - -As a final example, let's suppose that we need to create output -football league tables in a number of formats. Perhaps we are -passing this data on to other people and they can't all use the -same format. Some of our users need CSV files and others need -XML. Some require data split between home and away matches and -other just want the totals. In total, then, we'll need four -different templates, but the good news is that they can use the -same data object. All the script needs to do is to establish -which template is required and process it. - - use FootballLeague; - use Template; - - my ($name, $type, $stats) = @_; - - my $league = FootballLeague->new(name => $name); - - my $tt = Template->new; - - $tt->process("league_${type}_$stats.tt", - { league => $league } - "league_$stats.$type") - || die $tt->error; - -For example, you can call this script as - - league.pl 'English Premier' xml split - -This will process a template called C<league_xml_split.tt> -and put the results in a file called C<league_split.xml>. - -This starts to show the true strength of the Template Toolkit. -If we later wanted to add another file format - perhaps we -wanted to create a league table HTML page or even a LaTeX -document - then we would just need to create the appropriate -template and name it according to our existing naming -convention. We would need to make no changes to the code. - -I hope you can now see why the Template Toolkit is fast becoming -an essential part of many people's Perl installation. - -=head1 AUTHOR - -Dave Cross E<lt>dave@dave.org.ukE<gt> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - -Copyright (C) 2001 Dave Cross E<lt>dave@dave.org.ukE<gt> - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Tutorial/Web.pod b/lib/Template/Tutorial/Web.pod deleted file mode 100644 index a5ed9bb..0000000 --- a/lib/Template/Tutorial/Web.pod +++ /dev/null @@ -1,801 +0,0 @@ -#============================================================= -*-perl-*- -# -# Template::Tutorial::Web -# -# DESCRIPTION -# This tutorial provides an introduction to the Template Toolkit and -# a "quick start" guide to getting up to speed. Its primarily focus -# is on using the Template Toolkit to build web content and it covers -# 4 basic areas: using tpage and ttree; using the Template.pm module -# in CGI scripts; writing Apache/mod_perl handlers; and extending the -# toolkit by writing plugins. -# -# AUTHOR -# Andy Wardley <abw@andywardley.com> -# -# COPYRIGHT -# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved. -# Copyright (C) 1998-2001 Canon Research Centre Europe Ltd. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# -# -#======================================================================== - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Tutorial::Web - Generating Web Content Using the Template Toolkit - -=head1 DESCRIPTION - -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 L<tpage|Template::Tools::tpage> and -L<ttree|Template::Tools::ttree> scripts and then goes on to -show dynamic content generation using CGI scripts and Apache/mod_perl -handlers. - -Various features of the Template Toolkit are introduced and described -briefly and explained by use of example. For further information, -see L<Template>, L<Template::Manual> and the various sections within -it. e.g. - - perldoc Template # Template.pm module usage - perldoc Template::Manual # index to manual - perldoc Template::Manual::Config # e.g. configuration options - -The documentation is now also distributed in HTML format (or rather, -in the form of HTML templates). See the 'docs' sub-directory of the -distribution for further information on building the HTML documentation. - -If you're already reading this as part of the HTML documentation, then -you don't need to worry about all that. You can have a seat, sit back. - back and enjoy the rest of the tutorial... - -=head1 INTRODUCTION - -The Template Toolkit is a set of Perl modules which collectively -implement a template processing system. In this context, a template -is a text document containing special markup tags called 'directives'. -A directive is an instruction for the template processor to perform -some action and substitute the result into the document in place of -the original directive. Directives include those to define or insert -a variable value, iterate through a list of values (FOREACH), declare -a conditional block (IF/UNLESS/ELSE), include and process another template -file (INCLUDE) and so on. - -In all other respects, the document is a plain text file and may -contain any other content (e.g. HTML, XML, RTF, LaTeX, etc). Directives -are inserted in the document within the special markup tags which are -'[%' and '%]' by default, but can be changed via the module -configuration options. Here's an example of an HTML document with -additional Template Toolkit directives. - - [% INCLUDE header - title = 'This is an HTML example' - %] - - <h1>Some Interesting Links</h1> - - [% webpages = [ - { url => 'http://foo.org', title => 'The Foo Organisation' } - { url => 'http://bar.org', title => 'The Bar Organisation' } - ] - %] - - Links: - <ul> - [% FOREACH link = webpages %] - <li><a href="[% link.url %]">[% link.title %]</a> - [% END %] - </ul> - - [% INCLUDE footer %] - -This example shows how the INCLUDE directive is used to load and process -separate 'header' and 'footer' template files, including the output in -the current document. These files might look like this: - -header: - - <html> - <head> - <title>[% title %]</title> - </head> - - <body bgcolor="#ffffff"> - -footer: - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -The example also uses the FOREACH directive to iterate through the -'webpages' 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 'url' and 'title' member. The FOREACH directive -iterates through the list, aliasing 'link' to each item (hash ref). -The B<[% link.url %]> and B<[% link.title %]> directives then access -the individual values in the hash and insert them into the document. - -The following sections show other ways in which data can be defined for -use in a template. - -=head1 GENERATING STATIC PAGES - -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 -F<tpage> script. This is provided as part of the Template Toolkit and -should be installed in your usual Perl bin directory. - -Assuming you saved your template file as 'mypage.html', you would run -the command: - - tpage mypage.html - -This will process the template file, sending the output to STDOUT -(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 such as '.atml' (for 'Another Template Markup -Language', perhaps?) and the regular '.html' for the output files -(assuming you're creating HTML, that is). Alternatively, you might -redirect the output to another directory. e.g. - - tpage mypage.atml > mypage.html - tpage templates/mypage.html > html/mypage.html - -The B<tpage> script is very basic and only really intended to give you -an easy way to process a template without having to write any Perl code. -A much more flexible tool is B<ttree>, described below, but for now let's -look at the output generated by processing the above example (some -whitespace removed for brevity): - - <html> - <head> - <title>This is an HTML example</title> - </head> - - <body bgcolor="#ffffff"> - - <h1>Some Interesting Links</h1> - - Links: - <ul> - <li><a href="http://foo.org">The Foo Organsiation</a> - <li><a href="http://bar.org">The Bar Organsiation</a> - </ul> - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -The F<header> and F<footer> 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 HTML list. - -The F<ttree> script, also distributed as part of the Template Toolkit, -provides a more flexible way to process template documents. The first -time you run the script, it will ask you if it should create a -configuration file, usually called '.ttreerc' in your home directory. -Answer 'y' to have it create the file. - -The F<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. - - perldoc ttree - ttree -h - -In brief, the configuration file describes the directories in which -template files are to be found (src), where the corresponding output -should be written to (dest), and any other directories (lib) that may -contain template files that you plan to INCLUDE into your source -documents. You can also specify processing options (such as 'verbose' -and 'recurse') and provide regular expression to match files that you -don't want to process (ignore, accept) or should be copied instead of -processed (copy). - -An example F<.ttreerc> file is shown here: - -$HOME/.ttreerc: - 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 = ^# - -You can create many different configuration files and store them -in the directory specified in the 'cfg' option, shown above. You then -add the C<-f filename> option to F<ttree> to have it read that file. - -When you run the script, it compares all the files in the 'src' directory -(including those in sub-directories if the 'recurse' option is set), with -those in the 'dest' 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 C<-a> option forces all files to be processed, regardless of -modification times. - -The script I<doesn't> process any of the files in the 'lib' directory, -but it does add it to the INCLUDE_PATH for the template processor so -that it can locate these files via an INCLUDE or PROCESS directive. -Thus, the 'lib' directory is an excellent place to keep template elements -such as header, footers, etc., that aren't complete documents in their -own right. - -You can also specify various Template Toolkit options from the configuration -file. Consult the B<ttree> documentation and help summary (C<ttree -h>) -for full details. e.g. - -$HOME/.ttreerc: - pre_process = config - interpolate - post_chomp - -The 'pre_process' option allows you to specify a template file which -should be processed before each file. Unsurprisingly, there's also a -'post_process' option to add a template after each file. In the -fragment above, we have specified that the 'config' template should be -used as a prefix template. We can create this file in the 'lib' -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 HTML 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 'header' file. - -$lib/config: - - [% root = '~/abw' - home = "$root/index.html" - images = "$root/images" - email = 'abw@wardley.org' - graphics = 1 - webpages = [ - { url => 'http://foo.org', title => 'The Foo Organsiation' } - { url => 'http://bar.org', title => 'The Bar Organsiation' } - ] - %] - -Assuming you've created or copied the 'header' and 'footer' files from the -earlier example into your 'lib' directory, you can now start to create -web pages like the following in your 'src' directory and process them -with F<ttree>. - -$src/newpage.html: - - [% 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 %] - -Here we've shown how pre-defined variables can be used as flags to -enable certain feature (e.g. 'graphics') and to specify common items -such as an email address and URL'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. - -When you run B<ttree>, you should see output similar to the following -(assuming you have the verbose flag set). - - ttree 1.14 (Template Toolkit version 1.02a) - - 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 - -The '+' before 'newpage.html' 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 '-' and giving a reason why the file wasn't processed. - - - newpage.html (not modified) - -It has detected a 'newpage.html' 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 C<-a> option. You can also specify one or more filenames as -command line arguments to F<ttree>: - - tpage newpage.html - -This is what the destination page looks like. - -$dest/newpage.html: - - <html> - <head> - <title>Another Template Toolkit Test Page</title> - </head> - - <body bgcolor="#ffffff"> - - <a href="~/abw/index.html">Home</a> - <a href="mailto:abw@wardley.org">Email me</a> - - <img src="~/abw/images/logo.gif" align=right width=60 height=40> - - <hr> - - <center> - © Copyright 2000 Me, Myself, I - </center> - - </body> - </html> - -You can add as many documents as you like to the 'src' directory and -F<ttree> 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. - -=head1 DYNAMIC CONTENT GENERATION VIA CGI SCRIPT - -The L<Template|Template> module provides a simple front-end to the Template -Toolkit for use in CGI scripts and Apache/mod_perl handlers. Simply -'use' the Template module, create an object instance with the new() -method and then call the process() 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: - - #!/usr/bin/perl -w - - use strict; - 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"; - -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: - - 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', - }); - -Note that here we specify the 'config' file as a PRE_PROCESS 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 process() method. - -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. - -Here's a more detailed example to look over. Amongst the different -template variables we define in C<$vars>, we create a reference to a -CGI object and a 'get_user_projects' sub-routine. - - #!/usr/bin/perl -w - - use strict; - 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(); - -Here's a sample template file that we might create to build the output -for this script. - -$src/userinfo.html: - - [% 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 = worklist(me.id) %] - <li> <a href="[% project.url %]">[% project.name %]</a> - [% END %] - </ul> - - [% INCLUDE footer %] - -This example shows how we've separated the Perl implementation (code) from -the presentation (HTML) which 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 CGI scripts, you can give them the same consistency -as your static pages built via L<ttree|Template::Tools::ttree> or -other means. - -Furthermore, we can modify our script so that it processes any one of a -number of different templates based on some condition. A CGI 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. - -=head1 DYNAMIC CONTENT GENERATION VIA APACHE/MOD_PERL HANDLER - -B<NOTE:> the Apache::Template module is now available from CPAN -and provides a simple and easy to use Apache/mod_perl interface to the -Template Toolkit. It's only in it's first release (0.01) at the time -of writing and it currently only offers a fairly basic facility, but -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. - -The Template module can be used in a similar way from an Apache/mod_perl -handler. Here's an example of a typical Apache F<httpd.conf> file: - - 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> - -This defines a location called '/user/bin' to which all requests will -be forwarded to the handler() method of the MyOrg::Apache::User -module. That module might look something like this: - - 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; - } - -The handler accepts the request and uses it to determine the 'websrc_root' -value from the config file. This is then used to define an INCLUDE_PATH -for a new Template object. The URI is extracted from the request and a -CGI object is created. These are both defined as template variables. - -The name of the template file itself is taken from the PATH_INFO element -of the request. In this case, it would comprise the part of the URL -coming after '/user/bin', e.g for '/user/bin/edit', the template file -would be 'edit' located in "$websrc/src/user". The headers are sent -and the template file is processed. All output is sent directly to the -print() method of the Apache request object. - -=head1 USING PLUGINS TO EXTEND FUNCTIONALITY - -As we've already shown, it is possible to bind Perl data and functions -to template variables when creating dynamic content via a CGI 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 USE directive. - -The main benefit to this approach is that you can load the extension into -any template document, even those that are processed "statically" by -F<tpage> or F<ttree>. You I<don't> need to write a Perl wrapper to -explicitly load the module and make it available via the stash. - -Let's demonstrate this principle using the DBI plugin written by Simon -Matthews E<lt>sam@knowledgepool.comE<gt>. You can create this -template in your 'src' directory and process it using F<ttree> to see -the results. Of course, this example relies on the existence of the -appropriate SQL 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. - - [% 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 = 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 %] - -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 -F<Template::Plugin> module. - -Here's an example which defines some data items ('foo' and 'people') -and also an object method ('bar'). We'll call the plugin 'FooBar' for -want of a better name and create it in the 'MyOrg::Template::Plugin::FooBar' -package. We've added a 'MyOrg' to the regular 'Template::Plugin::*' package -to avoid any conflict with existing plugins. - -You can create a module stub using the Perl utlity F<h2xs>: - - h2xs -A -X -n MyOrg::Template::Plugin::FooBar - -This will create a directory structure representing the package name -along with a set of files comprising your new module. You can then -edit FooBar.pm to look something like this: - - package MyOrg::Template::Plugin::FooBar; - - use Template::Plugin; - use vars qw( $VERSION ); - use base qw( Template::Plugin ); - - $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; - } - -The plugin constructor new() 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 '_CONTEXT' 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, 'foo' and 'people' 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 -USE directive, such as the data source parameter, 'dbi:mSQL:mydbname', -that we used in the earlier DBI example. - -If you used F<h2xs> to create the module stub then you'll already -have a Makefile.PL and you can incite the familiar incantation to -build and install it. Don't forget to add some tests to test.pl! - - perl Makefile.PL - make - make test - make install - -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 PERL5LIB environment variable to specify another location. -If you're using F<ttree> then you can add the following line to your -configuration file instead. This has the effect of add '/path/to/modules' -to the @INC array to a similar end. - -$HOME/.ttreerc: - - perl5lib = /path/to/modules - -One further configuration item must be added to inform the toolkit of -the new package name we have adopted for our plugins: - -$HOME/.ttreerc: - - plugin_base = 'MyOrg::Template::Plugin' - -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. - - use Template; - - my $template = Template->new({ - PLUGIN_BASE => 'MyOrg::Template::Plugin' - }); - -Now we can create a template which uses this plugin: - - [% 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 %] - -The 'foo', 'bar' and 'people' items of the FooBar plugin are -automatically resolved to the appropriate data items or method calls -on the underlying object. - -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. - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 Canon Research Centre Europe Ltd. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - - - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: |
