great and in my personal mission to encourage people not to embed HTML in perl scripts, here is a few examples to get you started. I've tried to cover things I didn't get when I first started and could have saved me some work.
Lazy form handling with associate
HTML::Template has a cunning feature which I didn't notice in my first few passes through the documentation. You can give it your CGI object and it will fill in template values with them.
color1.tmpl:
<form action="color.pl" method="post">
<p>Your name: <input type="text" name="name"
value="<TMPL_VAR NAME=NAME>"></p>
<p>Your favorite color: <input type="text" name="color"
value="<TMPL_VAR NAME=COLOR>"></p>
<p><input type="submit"></p>
</form>
color2.tmpl:
<p>Hello, <b><TMPL_VAR NAME=NAME></b>. A little
birdy told me your favorite color is <b><TMPL_VAR NAME=COLOR></b>.
color.pl:
use CGI;
use HTML::Template;
my $cgi = CGI->new;
my $template;
print $cgi->header;
if ($cgi->param('name') && $cgi->param('color')) {
$template = 'color2';
} else {
$template = 'color1';
}
my $t = HTML::Template->new(filename => "$template.tmpl", associate =>
+ $cgi);
print $t->output;
Cheap Database Output
You want to output a table but are too lazy to code something?
HTML::Template to the rescue!
param() needs hashrefs and arrayrefs and the DBI functions
selectall_hashref and
fetchrow_hashref come in very handy.
Perl code:
use DBI;
use CGI;
use HTML::Template;
my $cgi = CGI->new;
my $dbh = DBI->connect('dbi:mysql:xxxx:localhost', 'xxxx', 'xxxx');
my $t = HTML::Template->new(filename => 'db.tmpl');
$t->param(ROWS => $dbh->selectall_hashref('select id, name, price from
+ products'));
$dbh->disconnect;
print $cgi->header;
print $t->output;
Template code:
<table border="1">
<tr><th>ID</th><th>NAME</th><th>PRICE</th></tr>
<TMPL_LOOP ROWS>
<tr>
<td><TMPL_VAR NAME=ID></td>
<td><TMPL_VAR NAME=NAME></td>
<td><TMPL_VAR NAME=PRICE></td>
</tr>
</TMPL_LOOP>
</table>
Doing a little bit more...
Perl code:
[snip]
my $rows = $dbh->selectall_hashref('select id, name, price from produc
+ts');
$dbh->disconnect;
my $sum = 0;
my $i = 0;
foreach (@$rows) {
$_->{odd} = $i++ % 2;
$sum += $_->{price};
}
$t->param(ROWS => $rows, TOTAL => $sum);
Template:
<table border="1">
<tr><th>ID</th><th>NAME</th><th>PRICE</th></tr>
<TMPL_LOOP ROWS>
<tr bgcolor="#<TMPL_IF ODD>666666<TMPL_ELSE>EEEEEE</TMPL_IF>">
<td><TMPL_VAR NAME=ID></td>
<td><TMPL_VAR NAME=NAME></td>
<td><TMPL_VAR NAME=PRICE></td>
</tr>
</TMPL_LOOP>
</table>
<p>The total is <TMPL_VAR NAME=TOTAL></p>
But I need to process my db output!
I often find I need to do a little work on what's in the database and handling it row by row is easier.
Note the array created so I can pass the same thing every time I create a template. I usually have cache on as I am running under mod_perl and this speeds things up a bit, I tend to turn off strict and die_on_bad_params as I'd rather things looked a bit funky than the script die (especially if it isn't me editing it).
Perl code:
use DBI;
use CGI;
use HTML::Template;
my $cgi = CGI->new;
my $dbh = DBI->connect('dbi:mysql:xxxx:localhost', 'xxxxx', 'xxxx');
my @tmpl_opts = (cache => 1, die_on_bad_params => 0, associate => $cgi
+);
my $sth = $dbh->prepare('select id, name, price, saleprice from produc
+ts');
my ($id, $name, $price, $saleprice);
my $i = 0;
my $sum = 0;
$sth->execute;
$sth->bind_columns(\($id, $name, $price, $saleprice));
while ($sth->fetch) {
my $real_price = $price < $saleprice ? $price : $saleprice;
$name =~ s/\b(\w)(\w+)\b/\U$1\L$2/g;
push @rows, { ID => lc($id), PRICE => $real_price, NAME => $name,
+ODD => $i++ %2 };
$sum += $real_price;
}
$sth->finish;
my $t = HTML::Template->new(filename => 'db2.tmpl', @tmpl_opts);
$t->param(ROWS => \@rows, TOTAL => $sum);
print $cgi->header;
print $t->output;
$dbh->disconnect;
Fin
Hope you liked it :)
gav^