<?xml version="1.0" encoding="windows-1252"?>
<node id="144315" title="using CGI, DBI and HTML::Template (a mini tutorial with example code)" created="2002-02-08 23:13:03" updated="2005-08-14 16:20:36">
<type id="120">
perlmeditation</type>
<author id="128665">
gav^</author>
<data>
<field name="doctext">
I find [CPAN://HTML::Template] 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.&lt;readmore&gt;
&lt;h1&gt;Lazy form handling with associate&lt;/h1&gt;
[CPAN://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.
&lt;h2&gt;color1.tmpl:&lt;/h2&gt;
&lt;code&gt;
&lt;form action="color.pl" method="post"&gt;
&lt;p&gt;Your name: &lt;input type="text" name="name" 
  value="&lt;TMPL_VAR NAME=NAME&gt;"&gt;&lt;/p&gt;
&lt;p&gt;Your favorite color: &lt;input type="text" name="color"
  value="&lt;TMPL_VAR NAME=COLOR&gt;"&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type="submit"&gt;&lt;/p&gt;
&lt;/form&gt;
&lt;/code&gt;
&lt;h2&gt;color2.tmpl:&lt;/h2&gt;
&lt;code&gt;
&lt;p&gt;Hello, &lt;b&gt;&lt;TMPL_VAR NAME=NAME&gt;&lt;/b&gt;. A little
birdy told me your favorite color is &lt;b&gt;&lt;TMPL_VAR NAME=COLOR&gt;&lt;/b&gt;.
&lt;/code&gt;
&lt;h2&gt;color.pl:&lt;/h2&gt;
&lt;code&gt;
use CGI;
use HTML::Template;

my $cgi = CGI-&gt;new; 
my $template;

print $cgi-&gt;header;

if ($cgi-&gt;param('name') &amp;&amp; $cgi-&gt;param('color')) {
    $template = 'color2';
} else {
    $template = 'color1';
}

my $t = HTML::Template-&gt;new(filename =&gt; "$template.tmpl", associate =&gt; $cgi);
print $t-&gt;output;
&lt;/code&gt;
&lt;h1&gt;Cheap Database Output&lt;/h1&gt;
You want to output a table but are too lazy to code something? [CPAN://HTML::Template] to the rescue! &lt;tt&gt;param()&lt;/tt&gt; needs hashrefs and arrayrefs and the DBI functions &lt;tt&gt;selectall_hashref&lt;/tt&gt; and &lt;tt&gt;fetchrow_hashref&lt;/tt&gt; come in very handy.
&lt;h2&gt;Perl code:&lt;/h2&gt;
&lt;code&gt;
use DBI;
use CGI;
use HTML::Template;

my $cgi = CGI-&gt;new;
my $dbh = DBI-&gt;connect('dbi:mysql:xxxx:localhost', 'xxxx', 'xxxx');
my $t = HTML::Template-&gt;new(filename =&gt; 'db.tmpl');

$t-&gt;param(ROWS =&gt; $dbh-&gt;selectall_hashref('select id, name, price from products'));

$dbh-&gt;disconnect;

print $cgi-&gt;header;
print $t-&gt;output;
&lt;/code&gt;
&lt;h2&gt;Template code:&lt;/h2&gt;
&lt;code&gt;
&lt;table border="1"&gt;
&lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;NAME&lt;/th&gt;&lt;th&gt;PRICE&lt;/th&gt;&lt;/tr&gt;

&lt;TMPL_LOOP ROWS&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=ID&gt;&lt;/td&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=NAME&gt;&lt;/td&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=PRICE&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/TMPL_LOOP&gt;

&lt;/table&gt;
&lt;/code&gt;
&lt;h1&gt;Doing a little bit more...&lt;/h1&gt;
&lt;h2&gt;Perl code:&lt;/h2&gt;
&lt;code&gt;
[snip]

my $rows = $dbh-&gt;selectall_hashref('select id, name, price from products');
$dbh-&gt;disconnect;

my $sum = 0; 
my $i = 0;

foreach (@$rows) {
    $_-&gt;{odd} = $i++ % 2;
    $sum += $_-&gt;{price};
}

$t-&gt;param(ROWS =&gt; $rows, TOTAL =&gt; $sum);
&lt;/code&gt;
&lt;h2&gt;Template:&lt;/h2&gt;
&lt;code&gt;
&lt;table border="1"&gt;
&lt;tr&gt;&lt;th&gt;ID&lt;/th&gt;&lt;th&gt;NAME&lt;/th&gt;&lt;th&gt;PRICE&lt;/th&gt;&lt;/tr&gt;

&lt;TMPL_LOOP ROWS&gt;
    &lt;tr bgcolor="#&lt;TMPL_IF ODD&gt;666666&lt;TMPL_ELSE&gt;EEEEEE&lt;/TMPL_IF&gt;"&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=ID&gt;&lt;/td&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=NAME&gt;&lt;/td&gt;
        &lt;td&gt;&lt;TMPL_VAR NAME=PRICE&gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/TMPL_LOOP&gt;

&lt;/table&gt;

&lt;p&gt;The total is &lt;TMPL_VAR NAME=TOTAL&gt;&lt;/p&gt;
&lt;/code&gt;
&lt;h1&gt;But I need to process my db output!&lt;/h1&gt;
I often find I need to do a little work on what's in the database and handling it row by row is easier.&lt;p&gt; Note the array created so I can pass the same thing every time I create a template. I usually have &lt;tt&gt;cache&lt;/tt&gt; on as I am running under mod_perl and this speeds things up a bit, I tend to turn off &lt;tt&gt;strict&lt;/tt&gt; and &lt;tt&gt;die_on_bad_params&lt;/tt&gt; as I'd rather things looked a bit funky than the script die (especially if it isn't me editing it).
&lt;h2&gt;Perl code:&lt;/h2&gt;
&lt;code&gt;
use DBI;
use CGI;
use HTML::Template;

my $cgi = CGI-&gt;new;
my $dbh = DBI-&gt;connect('dbi:mysql:xxxx:localhost', 'xxxxx', 'xxxx');

my @tmpl_opts = (cache =&gt; 1, die_on_bad_params =&gt; 0, associate =&gt; $cgi);

my $sth = $dbh-&gt;prepare('select id, name, price, saleprice from products');

my ($id, $name, $price, $saleprice);

my $i = 0;
my $sum = 0;

$sth-&gt;execute;
$sth-&gt;bind_columns(\($id, $name, $price, $saleprice));

while ($sth-&gt;fetch) {
    my $real_price = $price &lt; $saleprice ? $price : $saleprice;
    $name =~ s/\b(\w)(\w+)\b/\U$1\L$2/g;
    push @rows, { ID =&gt; lc($id), PRICE =&gt; $real_price, NAME =&gt; $name, ODD =&gt; $i++ %2 };
    $sum += $real_price;
}

$sth-&gt;finish;

my $t = HTML::Template-&gt;new(filename =&gt; 'db2.tmpl', @tmpl_opts);
$t-&gt;param(ROWS =&gt; \@rows, TOTAL =&gt; $sum);

print $cgi-&gt;header;
print $t-&gt;output;

$dbh-&gt;disconnect;
&lt;/code&gt;
&lt;h2&gt;Fin&lt;/h2&gt;
Hope you liked it :)
&lt;p&gt;gav^</field>
</data>
</node>
