sub-routine.
#!/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();
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'
%]
Email [% me.name %]
This is version [% version %]
Projects
[% INCLUDE footer %]
This example shows how we've separated the Perl implementation (code) from the
presentation (HTML). 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 CGI scripts, you
can give them the same consistency as your static pages built via
L 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 the L module is available from CPAN 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.
The L module can be used from an Apache/mod_perl handler. Here's an
example of a typical Apache F file:
PerlModule CGI;
PerlModule Template
PerlModule MyOrg::Apache::User
PerlSetVar websrc_root /home/abw/websrc
SetHandler perl-script
PerlHandler MyOrg::Apache::User
This defines a location called C to which all requests will
be forwarded to the C method of the C
module. That module might look something like this:
package MyOrg::Apache::User;
use strict;
use Apache::Constants qw( :common );
use Template;
use CGI;
our $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 C
value from the config file. This is then used to define an C
for a new L object. The URI is extracted from the request and a
L object is created. These are both defined as template variables.
The name of the template file itself is taken from the C element
of the request. In this case, it would comprise the part of the URL
coming after C, e.g for C, the template file
would be C located in C<$websrc/src/user>. The headers are sent
and the template file is processed. All output is sent directly to the
C 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 C