jdtoronto has asked for the wisdom of the Perl Monks concerning the following question:

The documentation for HTML::Template in this regards is rather scant.

I actually need to produce a small calendar and after happening upon Calendar Array I thought the maiden's prayer had at last been answered. Alas it was not to be the case!

The code, from rob_au's original was entered like this...

#!/usr/bin/perl -w use Data::Dumper; use Date::Calc qw/Day_of_Week Days_in_Month/; use strict; print STDOUT Dumper(&calendar_array); exit 0; sub calendar_array (;$$) { my $year = ($_[0] =~ /^\d{4}$/) ? $_[0] : (((localtime)[5]) + 1900 +); my $month = (($_[1] =~ /^\d+$/) && (($_[1] > 0) && ($_[1] < 13))) +? $_[1] : (((localtime)[4]) + 1); print "Year: $year : Month: $month \n"; my (@calendar, @output); my $day = 1 - Day_of_Week($year, $month, 1); while ($#calendar < 41) { push (@calendar, (($day <= 0) || ($day > Days_in_Month($year, +$month))) ? '' : $day); ++$day; } for (my $row = 0; $row < 6; $row++) { my @columns; for (my $col = 0; $col < 7; $col++) { push (@columns, { 'day' => $calendar[$row * 7 + $col], }); } push (@output, { 'row' => \@columns }); } return \@output; }
But such was not to be the case. Rob gave the template which looked like this:
<table border="0" cellpadding="2" cellspacing="0" width="140"> <tr> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>S</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>M</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>T</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>W</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>T</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>F</b></font></td> <td align="left" colspan="1" rowspan="1" valign="middle" width +="20"><font color="#000000" face="Tahoma, Verdana, Arial" size="2"><b +>S</b></font></td> </tr> <tmpl_loop "row"> <tr><tmpl_loop "day"> <td align="left" colspan="1" rowspan="1" valign="middl +e" width="20"><font color="#333333" face="Tahoma, Verdana, Arial" siz +e="2"><tmpl_var "day"></font></td> </tmpl_loop></tr> </tmpl_loop> </table>
But when these are coupled together like this (in a CGI::Application run_mode):
sub disp_cal { my $self = shift; my $form = $self->load_tmpl('calendar01.html', die_on_bad_params = +> 0); my $calendar = Calendar->calendar_array; print STDERR Dumper( $calendar ); $form->param( 'row' => $calendar ); my $output = $form->output; return $output; }
The darn thing falls flat on its face.

The OUTER loop ( row ) works, the HTML generated from the template has a single row of headings followed by SIX empty rows. WHY doesn't the inner loop ( day ) work?

Could somebody please put me out of my misery and tell me why?

jdtoronto

Replies are listed 'Best First'.
Re: Nested loops in HTML::Template
by Coruscate (Sexton) on Jan 20, 2004 at 06:28 UTC

    I don't know if it's your only problem, but you need to change push (@output, { 'row' => \@columns }); to push (@output, { 'day' => \@columns }); at least. The format you need to be returning from your sub is as follows:

    return [ { day => [ { day => '' }, { day => '' }, { day => 1 }, { day => 2 }, { day => 3 }, { day => 4 }, { day => 5 } ] }, { day => [ { day => 6 }, { day => 7 }, { day => 8 }, { day => 9 }, { day => 10 }, { day => 11 }, { day => 12 } ] } ];

    Update: After reverse engineering the data structure you're outputting from your subroutine, I do believe that is the only change you need to make (the one s/'row'/'day'/). It should then be fine as long as the match involved with your row/columing is correct.

      And in fact that change solves the problem!

      It seems to be another case of being too close to something for too long and not being able to see the problems! Thanks Coruscate

      Its 2:40am here now, so I am going to call it a day.

      jdtoronto

Re: Nested loops in HTML::Template
by Roger (Parson) on Jan 20, 2004 at 06:41 UTC
    Your code is almost working, you only need to change three words to fix it properly.
    $form->param( 'calendar' => $calendar ); # change row to calendar

    In HTML template:
    <tmpl_loop name="calendar"> <!-- change row to calendar --> <tr> <tmpl_loop name="row"> <!-- change day to row --> <td .... ><font ...><tmpl_var name="day"></font></td> </tmpl_loop> </tr> </tmpl_loop>