20.9.3. Discussion
Parameterized output for your CGI scripts is a good idea for many
reasons. Separating your program from its data lets other people (art
directors, for instance) change the HTML but not the program. Even
better, two programs can share the same template, so style changes in
the template are immediately reflected in both programs' output.
For example, suppose you have the first template from the Solution
stored in a file. Then your CGI program contains the definition of
the template subroutine shown earlier and makes
appropriate settings for variables $username,
$count, and $total. You can
fill in the template by simply using:
%fields = (
username => $whats_his_name,
count => $login_count,
total => $minute_used,
);
print template("/home/httpd/templates/simple.template", \%fields);
Example 20-7. userrep1
#!/usr/bin/perl -w
# userrep1 - report duration of user logins using SQL database
use DBI;
use CGI qw(:standard);
# template( ) defined as in the Solution section above
$user = param("username") or die "No username";
$dbh = DBI->connect("dbi:mysql:connections:mysql.domain.com",
"connections", "seekritpassword") or die "Couldn't connect\n";
$sth = $dbh->prepare(<<"END_OF_SELECT") or die "Couldn't prepare SQL";
SELECT COUNT(duration),SUM(duration)
FROM logins WHERE username='$user'
END_OF_SELECT
# this time the duration is assumed to be in seconds
if (@row = $sth->fetchrow_array( )) {
($count, $seconds) = @row;
} else {
($count, $seconds) = (0,0);
}
$sth->finish( );
$dbh->disconnect;
print header( );
print template("report.tpl", {
'username' => $user,
'count' => $count,
'total' => $total
});
For a fancier, more flexible solution, look at the second template in
the Solution section, which relies upon the CPAN module
Text::Template. Contents of braces found within the template file are
evaluated as Perl code. Ordinarily, these substitutions are just
simple variables:
You owe: {$total}
but they can also include full expressions:
The average was {$count ? ($total/$count) : 0}.