http://qs321.pair.com?node_id=202304
Category: CGI Programming
Author/Contact Info jeffa
Description: Have you ever wanted to write an HTML::Template script that would display any database query without having to change the template file? Well, this bit of code attempts to do just that. Just supply a query and optional place holders and the code will do the rest. Of course, changing the layout of the table is a manual process, but the number and names of the columns are dynamically supplied.

NULL characters and HTML encodings are taken care of (via HTML::Entities for the latter), but i have only tested this code with the MySQL relational database server. Comments and suggestions are always welcome.

use strict;
use warnings;
use DBI;
use HTML::Entities;
use HTML::Template;

my $dbh = DBI->connect(
   qw(DBI:vendor:database:host user pass),
   {RaiseError=>1}
);

# change these two vars to suite your needs:
my @arg = (42);
my $sql = 'select foo,bar from baz where qux = ?';

my $sth = $dbh->prepare($sql);
$sth->execute(@arg);

my $stmt  = $sth->{Statement};
my $field = $sth->{NAME};
my $row   = $sth->fetchall_arrayref();
my $tmpl  = HTML::Template->new(filehandle => \*DATA);

$tmpl->param(
   query  => $stmt,
   fields => [
      map {
         { field => ucfirst lc $_ }
      } @$field 
   ],
   rows => [
      map {{ cols => [ 
         map {
            { data => defined $_ ? encode_entities $_ : ' ' }
         } @$_ 
      ] }} @$row
   ],
);

print $tmpl->output;

$dbh->disconnect;

__DATA__
<html>

<head>
<title>Dynamic table template</title>
<style type="text/css">
<!--
   table { border-style: outset; border-width: thin; width: 70% }
   th    { border-style: ridge; }
   td    { border-style: inset; }
-->
</style>
</head>

<body>

<table>
  <thead>
  <caption><tmpl_var query></caption>
  <tr>
  <tmpl_loop fields>
     <th><tmpl_var field></th>
  </tmpl_loop>
  </tr>
  </thead>

  <tbody>
  <tmpl_loop rows>
  <tr>
     <tmpl_loop cols>
        <td><tmpl_var data></td>
     </tmpl_loop>
  </tr>
  </tmpl_loop>
  </tbody>
</table>

</body>
</html>