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

I've got another question about the HTML::Template module. I want to repeat a certain block of HTML-Tags according to a given number. In my case: I want to create a table with X columns. Right now I don't know how to make that simple step possible. I tried a TMPL_LOOP, but in my understanding it needs an array ref, filled with hash refs. So I tried to make a hash array with X entries (X is the amount of columns) and tried to repeat the (td) block for every entry in it. But that doesn't work at all.. Is there an easier way, or do I have to do it like that and just make a mistake?Because I get the following error message:

HTML::Template->output() : fatal error in loop output : HTML::Template + : Attempt to set nonexistent parameter 'schedule_columns' - this par +ameter name doesn't match any declarations in the template file : (die_on_bad_par +ams => 1) at D:/Programme/Perl814/lib/HTML/Template.pm line 3304 at martin3.pl line 121

Here's the TMPL-part:

<TMPL_LOOP NAME=DATA_STRUCTURE> <TMPL_IF NAME=BGCOLOR_CUSTOMER> <tr> <TMPL_ELSE> <tr bgcolor="white"> </TMPL_IF> <th><TMPL_VAR NAME=CUSTOMER></th> <th><TMPL_VAR NAME=DOMAIN></th> <td> <TMPL_IF NAME=EXPORT_VALUE> <table style="Width:100%"> <TMPL_LOOP NAME=SCHEDULE_ROWS> <tr> <TMPL_LOOP NAME=SCHEDULE_COLUMNS> <td><b><TMPL_VAR NAME=SCHEDULE></b></t +d> </TMPL_LOOP> </tr> </TMPL_LOOP> </table> </TMPL_IF> </td> <td> <TMPL_IF NAME=IMPORT_VALUE> <table style="Width:100%"> <TMPL_LOOP NAME=SCHEDULE_ROWS> <tr> <TMPL_LOOP NAME=SCHEDULE_COLUMNS> <td><b><TMPL_VAR NAME=SCHEDULE></b></t +d> </TMPL_LOOP> </tr> </TMPL_LOOP> </table> </td> </TMPL_IF> </tr> </TMPL_LOOP>

Here's the PERL code:

for my $domain (keys %{$bi->{$customer}}) { my %data_structure; my @schedule_rows_loop; my @schedule_columns_loop; $data_structure{CUSTOMER}=$customer; $data_structure{DOMAIN}=$domain; for my $host (keys %{$bi->{$customer}->{$domain}}) { my $schedule = $bi->{$customer}->{$domain}->{$host}->{BACK +UPCFG}->{EXPORT_SCHEDULE_1}->{VALUE}; if (defined $schedule) +## Da nicht alle Kunden / Domainen zurzeit eine EXPORT_SCHEDULE haben { my $import_value=$bi->{$customer}->{$domain}->{$host}- +>{BACKUPCFG}->{IMPORT_ACTIVE_1}->{VALUE}; my $export_value=$bi->{$customer}->{$domain}->{$host}- +>{BACKUPCFG}->{EXPORT_ACTIVE_1}->{VALUE}; my $scheduled_export_days =convert_seconds_days(($bi-> +{$customer}->{$domain}->{$host}->{BACKUPCFG}->{EXPORT_BACKUP_LIFETIME +_SEC_1}->{VALUE})); $data_structure{IMPORT_VALUE}=$import_value; $data_structure{EXPORT_VALUE}=$export_value; my @schedule=split(/,/, $schedule); for my $dif_schedule(@schedule) { my %schedule_rows_data; $schedule_rows_data{SCHEDULE}=$dif_schedule; push (@schedule_rows_loop, \%schedule_rows_data); } for(my $i=0;$i<=$scheduled_export_days;$i++) { my %schedule_columns_data; $schedule_columns_data{SCHEDULE_COLUMNS_COUNT}=1; push (@schedule_columns_loop, \%schedule_columns_d +ata); } } } $data_structure{BGCOLOR_CUSTOMER}=$tr_bgcolor; $data_structure{SCHEDULE_ROWS} = \@schedule_rows_loop; $data_structure{SCHEDULE_COLUMNS} =\@schedule_columns_loop; push (@data_structure_loop, \%data_structure); print Dumper(\@data_structure_loop)."\n"; } } $template->param(DATA_STRUCTURE => \@data_structure_loop);

Replies are listed 'Best First'.
Re: HTML::Template question
by tangent (Parson) on Jul 21, 2015 at 12:59 UTC
    In your 'TMPL_IF NAME=EXPORT_VALUE' loop you would need a data structure like this:
    SCHEDULE_ROWS => [ { SCHEDULE_COLUMNS => [ { SCHEDULE => 'value' }, { SCHEDULE => 'value' }, ], }, ]
    And in 'TMPL_IF NAME=IMPORT_VALUE' loop you would need this:
    SCHEDULE_ROWS => [ { SCHEDULE => 'value' }, { SCHEDULE => 'value' }, ]
    But in your code you have:
    $data_structure{SCHEDULE_ROWS} = \@schedule_rows_loop; $data_structure{SCHEDULE_COLUMNS} =\@schedule_columns_loop;
    which gives you:
    SCHEDULE_ROWS => [ { SCHEDULE => 'value' }, { SCHEDULE => 'value' }, ], SCHEDULE_COLUMNS => [ { SCHEDULE_COLUMNS_COUNT => 'value' }, { SCHEDULE_COLUMNS_COUNT => 'value' }, ]
    Try changing the template to:
    <TMPL_LOOP NAME=SCHEDULE_ROWS> <tr> <td><b><TMPL_VAR NAME=SCHEDULE></b></td> </tr> </TMPL_LOOP> <TMPL_LOOP NAME=SCHEDULE_COLUMNS> <tr> <td><TMPL_VAR NAME=SCHEDULE_COLUMNS_COUNT></td> </tr> </TMPL_LOOP>

      That's not what I want to get from the Template. Sorry, I probably didn't explain it in a good way. I have a table which has X amount of rows and X amount of columns. The rows are generated through the "SCHEDULED_ROWS" loop, while the columns should be generated through the "SCHEDULED_COLUMNS" loop. For every row in the table, there is a schedule value. Now, I want to have this schedule value for more than 1 column. like this:

      20:00 20:00 20:00 20:00 20:00
      13:00 13:00 13:00 13:00 13:00
        That's not what I want to get from the Template
        I was pointing out where the problem is, and showing you that your template has conflicting requirements. You will need to change both your template and the way you construct the data structure. If you can show a correct template it should be possible to advise on the data structure.
Re: HTML::Template question
by 1nickt (Canon) on Jul 21, 2015 at 11:23 UTC

    The error message tells you:

    HTML::Template : Attempt to set no +nexistent parameter 'schedule_columns' - this parameter name doesn't match any declarations in the template file
    <TMPL_LOOP NAME=SCHEDULE_COLUMNS>
    The way forward always starts with a minimal test.

      But I don't know why, and how to fix it? It is in the template, and I give is part of the array ref I give the template(checked with Dumper)

        You haven't posted all the relevant code, so I was guessing from the error messages that you declare the parameter in upper case and then attempt to set it in lower case. Try searching for the string 'schedule_rows' in your code, then find where you declare that in your template file. I think you will find they are different.

        The way forward always starts with a minimal test.