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

Hi Monks,

I'm building an option list to be supplied as output to a template using HTML::Template (It's really cool - I just discovered. Thanks to bradcathey who helped with some sample code! (309583).

My code to build the list is as follows:

my $options = ''; while (my @ary = $sth->fetchrow_array()) { # $ary[0] holds the data's id # $ary[1] holds the data $options .= qq~<option value="$ary[0]">$ary[1]~; }
It works but I would like to know if there's a better way to do it.

20031206 Edit by Corion: Changed link style to id://

Replies are listed 'Best First'.
Re: Concatenating a list...
by allolex (Curate) on Dec 06, 2003 at 17:27 UTC

    This is the skeleton of something you might want to do with your template. Please take Anonymous Monk's advice and use HTML::Template's built-in functions instead of concatenation.

    #!/usr/bin/perl -T use strict; use warnings; use Carp; use HTML::Template; open my $file, "<", 'file.txt'; while (<$file>) { chomp; my($fn,$ln) = split /\t+/, $_ or carp "Row unreadable.\n"; push @loop_data, { firstname => $fn, lastname => $ln }; } my $template = HTML::Template->new(filename => 'template.tmpl'); print "Content-type: text/html\n\n"; $template->param(printlist => \@loop_data); print $template->output; <!-- Relevant part of a template: --> <table> <TMPL_LOOP NAME="printlist"> <tr> <td><TMPL_VAR ESCAPE=HTML NAME="firstname"></td> <td><TMPL_VAR ESCAPE=HTML NAME="lastname"></td> </tr> </TMPL_LOOP> </table>

    --
    Allolex

Re: Concatenating a list...
by bradcathey (Prior) on Dec 06, 2003 at 17:23 UTC
    My basic Perl skills notwithstanding, glad I could help. With a bit more help from fuzzyping with this node here's a way to use H::T's LOOP feature to solve it another way (though I have used your concatenating method many times). The Perl:
    #!/usr/bin/perl -w print "Content-type: text/html\n\n"; use HTML::Template; use strict; my @datalist; my $template = HTML::Template -> new(filename => "../htmlfilename.tmpl +"); while (my @ary = $sth->fetchrow_array()) { my %one_record = ( dataid => $ary[0], datalisting => $ary[1], ); push (@datalist, \%one_record); } $template->param(datalist => \@datalist); print $template->output();
    And the HTML snippet:
    <select name="xxxxx" size="4"> <tmpl_if datalist> <tmpl_loop name="datalist"> <option value="<tmpl_var name='dataid'>"><tmpl_var name='data +listing'></option> </tmpl_loop> </tmpl_if> </select>
    Caveat: I did not test it with a database, but using trial data in the script it worked fine. And thanks for a good question, I learned something in the process of answering it! What PM's is all about. Good luck.

    —Brad
    "A little yeast leavens the whole dough."
Re: Concatenating a list...
by Anonymous Monk on Dec 06, 2003 at 15:38 UTC
    Here's a tip, use HTML::Template to build the list, use the autoescaping features, avoid concatination :)
      I see allolex's point, but I'd like to see code showing "autoescaping" features. Not sure I am connecting the dots.

      Update
      Okay, I see what was meant, I thought it was being implied that *H::T* had autoescaping features.

      —Brad
      "A little yeast leavens the whole dough."

        All the HTML escaping does is make sure that things that have HTML entity codings are coded as such: ">" becomes &gt; and so on. It's a way of keeping the code-external data from messing up your output. That has the effect of helping to make sure your data isn't messed with maliciously. Every little bit helps :)

        --
        Allolex

Re: Concatenating a list...
by duff (Parson) on Dec 06, 2003 at 17:20 UTC

    I don't know about better per se, but I would probably write it like this:

    my $ar = $sth->fetchall_arrayref; $options = join "", map { qq~<option value="$_->[0]">$_->[1]~ } @$ar;

    But that's just the way I'm bent