What you want to do is possible, but requires
you to use an underused feature in HTML::Template
called loop_context_vars. Enabling it in the
new() constructor will allow you to use the
loop context variables: __FIRST__, __LAST__, __INNER__, __ODD__
inside your TMPL_IF or TMPL_UNLESS tags. To see what I
mean, check out the template example at the bottom of this post.
In particular, we care about the __ODD__ variable, which
will be set to true on the odd numbered passes. By testing this variable,
we can print either the <tr> or </tr>
tags when appropriate. Consider the following code:
#!/usr/bin/perl -w
use strict;
use HTML::Template;
my @scores = (
{ name => 'name1', score => 4 },
{ name => 'name2', score => 2 },
{ name => 'name3', score => 3 },
);
my $template = HTML::Template->new(
filename => 'scores.tmpl',
loop_context_vars => 1,
);
$template->param(scores => \@scores);
print $template->output;
Which loads a template that contains the following
text:
<table>
<TMPL_LOOP NAME='scores'>
<TMPL_IF NAME='__ODD__'>
<tr>
</TMPL_IF>
<td><TMPL_VAR NAME='name'></td><td><TMPL_VAR NAME='score'></td>
<TMPL_UNLESS NAME='__ODD__'>
</tr>
</TMPL_UNLESS>
</TMPL_LOOP>
</table>
This will iterate over the @scores and
print them in two columns in the table. There is only one
drawback to this approach, if the @scores has
an odd number of elements, the final </tr>
will not be printed. This can either be solved by pushing
an empty element onto the array, or creative
use of the __LAST__ and __ODD__
variables together. I personally prefer the latter and
try to offload presentation logic off to the
template, rather than pollute the code with special
exceptions.