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

Hi Monks!
I am trying to generate .html files using HTML::Template, but when the code runs it is repeating the whole content of the .tmpl file if rows of data are found. The "->output" should be outside of the while, but I just cant figure it out how I would write the files if I do that.
Here is a short version of the code that shows what I am trying to do.
#!/usr/bin/perl use strict; use warnings; use HTML::Template; use Data::Dumper; use File::Slurp; # Load Main Template my $data_tmpl = HTML::Template->new(filename => 'data.tmpl',); my $more_data = more_data(); my $alldata; while ( my ( $key, $entry ) = each %{ $more_data } ) { # Load into the template $data_tmpl->param( NAME => $entry->{'NAME'}, ); # load values into template $data_tmpl->param( NUMBER => $entry->{NUMBER}, DATE => $entry->{DATE}, COL => $entry->{COL}, FIRST => $entry->{FIRST}, LAST => $entry->{NAME}, ); $alldata .= $data_tmpl->output; # Uses file slurp for writing write_file("/location/".$key.".html", $alldata); }

Thanks for looking!

Replies are listed 'Best First'.
Re: HTML::Template output to files.
by Anonymous Monk on Apr 28, 2014 at 19:23 UTC

    So do I understand correctly you want one file per while loop execution? If so, here: $alldata .= $data_tmpl->output; you're appending the return value of $data_tmpl->output to $alldata (because you're using the .= operator instead of a plain = assignment), so you're accumulating all of the outputs in that variable, so each file you write will have more and more of the output collected. What happens if you remove that line and just write write_file("/location/$key.html", $data_tmpl->output); ? (note: untested)

    If you want just one large file, it should be enough to move the write_file after the while loop. Unless you want that file to have a header and a footer?

      I just re-read your post and am no longer sure what you want your output to look like. Perhaps you could provide a (simplified) template and and example of what output you expect?

      Are you perhaps looking for the <TMPL_LOOP> construct?

        I considered the loop but the output inside the while is not making sense to me. Here is a sample template if I would use the loop tag.
        <table> <tr> <td><TMPL_VAR NAME="NAME"></td> </tr> <TMPL_LOOP NAME=DATA> <tr> <td><TMPL_VAR NAME="NUMBER"></td> <td><TMPL_VAR NAME="DATE"></td> <td><TMPL_VAR NAME="COL"></td> <td><TMPL_VAR NAME="FIRST"></td> <td><TMPL_VAR NAME="LAST"></td> </tr> </TMPL_LOOP> </table>

        I am using without the loop tag:
        <table> <tr> <td><TMPL_VAR NAME="NAME"></td> </tr> <tr> <td><TMPL_VAR NAME="NUMBER"></td> <td><TMPL_VAR NAME="DATE"></td> <td><TMPL_VAR NAME="COL"></td> <td><TMPL_VAR NAME="FIRST"></td> <td><TMPL_VAR NAME="LAST"></td> </tr> </table>

        One output example:
        <table> <tr> <td>John Doe</td> </tr> <tr> <td>1111</td> <td>04/28/2014</td> <td>Code 4</td> <td>A</td> <td>B</td> </tr> <tr> <td>234</td> <td>04/28/2014</td> <td>Code 5</td> <td>A</td> <td>C</td> </tr> <tr> <td>6678</td> <td>05/28/2014</td> <td>Code 9</td> <td>B</td> <td>K</td> </tr> </table>

        Another:
        <table> <tr> <td>Mary ANn</td> </tr> <tr> <td>88766</td> <td>04/28/2014</td> <td>Code AX</td> <td>Q</td> <td>M</td> </tr> </table>

        I hope it's a little clear, thanks!
        I see, but I cant get the value for $entry->{'NAME'} unless I am inside of the WHILE and since there will be lots of files been created I need to use the value of $key to name these files. The value of $entry->{'NAME'} is one per file, it does not need to be in a loop. Once I have all the data pushed into the @data array how it would be possible to create the files for each $entry->{'NAME'} ?