<?xml version="1.0" encoding="windows-1252"?>
<node id="225054" title="Two tips for developing with HTML::Template" created="2003-01-07 14:49:12" updated="2005-05-21 09:11:00">
<type id="120">
perlmeditation</type>
<author id="22308">
dws</author>
<data>
<field name="doctext">
While developing a moderately complex system, I came up with two techniques that can ease the pain of using &lt;code&gt;HTML::Template&lt;/code&gt; 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.
&lt;p&gt;
&lt;b&gt;Wrap all calls in Eval&lt;/b&gt;
&lt;p&gt;
Since &lt;code&gt;HTML::Template&lt;/code&gt; likes to report errors to &lt;small&gt;STDERR&lt;/small&gt; via &lt;code&gt;die()&lt;/code&gt;,
you'll find yourself making frequent visits to your error logs. Doing something like the
following will direct those errors to your browser.
&lt;readmore&gt;
&lt;code&gt;  my $template;
  eval {
      $template = new HTML::Template(filename =&gt; 'foo.tmpl');
  };
  print $@ if $@;

  eval {
      $template-&gt;param(param1 =&gt; $somevalue);
      $template-&gt;param(param2 =&gt; $someothervalue);
  };
  print $@ if $@;

  eval {
      print $template-&gt;output();
  };
&lt;/code&gt;
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.
&lt;p&gt;
&lt;b&gt;Turning Templates into Error Logs&lt;/b&gt;
&lt;p&gt;
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:
&lt;p&gt;
In the template, switch between the error log and "normal" by embedding the following:
&lt;code&gt;  &lt;TMPL_IF debug&gt;
  &lt;ul&gt;
  &lt;TMPL_LOOP debuglog&gt;
    &lt;li&gt;&lt;TMPL_VAR item ESCAPE=HTML&gt;
  &lt;/TMPL_LOOP&gt;
  &lt;/ul&gt;
  &lt;TMPL_ELSE&gt;
  ... the non-debug page ...
  &lt;/TMPL_IF&gt;
&lt;/code&gt;
Use this by doing
&lt;code&gt;  my @debuglog = ();

  if ( ... ) {
      push @debuglog, {item =&gt; "Some message"};
  }
  ...
  $template-&gt;parameter(debug =&gt; 0 != @debuglog);
  $template-&gt;parameter(debuglog =&gt; \@debuglog);
&lt;/code&gt;
For convenience you can do something like
&lt;code&gt;  sub debuglog {
      push @debuglog, {item =&gt; $_} for ( @_ );
  }
&lt;/code&gt;
so that you can write
&lt;code&gt;  debuglog("Some message") if ( ... );
&lt;/code&gt;
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.
&lt;p&gt;
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".
&lt;p&gt;

</field>
</data>
</node>
