perlmeditation
dws
While developing a moderately complex system, I came up with two techniques that can ease the pain of using <code>HTML::Template</code> to build pages. These techniques probably aren't original, but I didn't see them in the POD or in a quick search through the PM archives.
<p>
<b>Wrap all calls in Eval</b>
<p>
Since <code>HTML::Template</code> likes to report errors to <small>STDERR</small> via <code>die()</code>,
you'll find yourself making frequent visits to your error logs. Doing something like the
following will direct those errors to your browser.
<readmore>
<code> my $template;
eval {
$template = new HTML::Template(filename => 'foo.tmpl');
};
print $@ if $@;
eval {
$template->param(param1 => $somevalue);
$template->param(param2 => $someothervalue);
};
print $@ if $@;
eval {
print $template->output();
};
</code>
The first eval catches typos in the template.
The second eval catches both mismatches in parameter names (e.g., "payrate" vs. "pay_rate").
I forget now what the third eval catches, but it did catch something odd for me once, so I recommend it.
Doing this cut my debug cycle in half.
<p>
<b>Turning Templates into Error Logs</b>
<p>
Instead of (or in addition to) dumping diagnostic information into a separate logfile,
it's possible to turn a template into an error log, via the following technique:
<p>
In the template, switch between the error log and "normal" by embedding the following:
<code> <TMPL_IF debug>
<ul>
<TMPL_LOOP debuglog>
<li><TMPL_VAR item ESCAPE=HTML>
</TMPL_LOOP>
</ul>
<TMPL_ELSE>
... the non-debug page ...
</TMPL_IF>
</code>
Use this by doing
<code> my @debuglog = ();
if ( ... ) {
push @debuglog, {item => "Some message"};
}
...
$template->parameter(debug => 0 != @debuglog);
$template->parameter(debuglog => \@debuglog);
</code>
For convenience you can do something like
<code> sub debuglog {
push @debuglog, {item => $_} for ( @_ );
}
</code>
so that you can write
<code> debuglog("Some message") if ( ... );
</code>
The beauty of this approach is that you get a debug log if there are problems, or a normal page if there aren't.
Debug cycles can be wickedly quick.
<p>
I adapted this scheme to report "normal" errors, and use it to give users a punch list of things to fix, like "Please provide a valid credit card number".
<p>