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

I'm coding a fairly simple form which allows users to add and/or edit postings. I'm using HTML::Template, and so far, it's been going great.

Following is an edited version of one of the templates:

<TMPL_LOOP NAME=NEWBODY> <P CLASS="std-title"><STRONG>Date</STRONG>: <TMPL_VAR NAME=node_date>< +BR> STRONG>By</STRONG>: <TMPL_VAR NAME=node_author> <P> <TMPL_VAR NAME=DisplayContent> <FORM ACTION="modify.pl" METHOD="POST"> <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1> <TR><TD>Title</TD> <TD><INPUT TYPE="TEXT" SIZE=100 NAME=node_title value="<TMPL_VAR NAME= +node_title>"></TD> </TR> <TR> <TD COLSPAN=2> <TEXTAREA COLS=100 ROWS=20 NAME=node_content><TMPL_VAR NAME=node_conte +nt></TEXTAREA> </TD> </TR> <TR><TD><INPUT TYPE="SUBMIT" NAME=action_name VALUE="<TMPL_VAR NAME=a +ction_name>"></TD></TR> <TD><INPUT TYPE="RESET" VALUE="Reset"></TD> </TR> </TABLE> </FORM> </TMPL_LOOP>

And here is the code that I'm using to populate the template:

my $SQLText = "SELECT node_id, node_title, node_date, node_author, nod +e_section, node_content FROM nodes WHERE $Column like ? ORDER BY node_date, node_title, node_author"; my $sth = $dbh->prepare($SQLText); my $query = $sth->execute($SearchParam); my $errno = $dbh->{'mysql_errno'}; my $error = $dbh->{'mysql_error'}; my $returnArray; push @{$returnArray}, $_ while $_ = $sth->fetchrow_hashref(); my $template = HTML::Template->new(filename => 'templates/mod-node.tmpl'); $template->param( DisplayContent => $DisplayContent, NEWBODY => $returnArray ); print $template->output;

As you can see, I'm using the TMPL_LOOP construct to simplify matters (greatly). However, I now find myself needing to add something like the following:

<select name="Type"> <option>Audit <option>New <option>Update </select>

The option items are variable and will be populated from a database.

Obviously, this can easily be handled with another TMPL_LOOP, but it will have to exist inside the current TMPL_LOOP. Setting up the form is straightforward, but I've run into a mind block as to how I would populate this item.

I'd post code to show my effort to date, but my coding time has mainly been spent reading through docs and staring blankly at the screen. Any assistance is, as always, greatly appreciated.

Thanks!

If things get any worse, I'll have to ask you to stop helping me.

Replies are listed 'Best First'.
(jeffa) Re: TMPL_LOOP within a TMPL_LOOP
by jeffa (Bishop) on Apr 30, 2002 at 03:04 UTC
    Piece of cake! You simply pass another array reference of hash references, just like $returnArray. But it looks like you have a problem with the parameter 'DisplayContent' - it is inside the TMPL_LOOP, so you have to include it inside $returnArray. Here is a semi-rewrite with some hard coded data (for ease of demonstration). You will need to rewrite this to retrieve the select data from your database.
    use strict; use HTML::Template; my $data = do {local $/; <DATA>}; my $template = HTML::Template->new( scalarref => \$data, ); my $returnArray = [ { node_date => 'some date', node_author => 'some author', DisplayContent => 'DisplayContent', node_title => 'some title', node_content => 'some content', action_name => 'some_action', select_name => 'Type', options => [ {opt => 'Audit'}, {opt => 'New'}, {opt => 'Update'}, ], }, { node_date => 'some other date', node_author => 'some other author', DisplayContent => 'DisplayContent', node_title => 'some other title', node_content => 'some other content', action_name => 'some_other_action', select_name => 'Type', options => [ {opt => 'Audit'}, {opt => 'New'}, {opt => 'Update'}, ], }, ]; $template->param( NEWBODY => $returnArray ); print $template->output; __DATA__ <TMPL_LOOP NAME=NEWBODY> <P CLASS="std-title"><STRONG>Date</STRONG>: <TMPL_VAR NAME=node_date>< +BR> STRONG>By</STRONG>: <TMPL_VAR NAME=node_author> <P> <TMPL_VAR NAME=DisplayContent> <FORM ACTION="modify.pl" METHOD="POST"> <TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1> <TR><TD>Title</TD> <TD><INPUT TYPE="TEXT" SIZE=100 NAME=node_title value="<TMPL_VAR NAME= +node_title>"></TD> </TR> <TR> <TD COLSPAN=2> <TEXTAREA COLS=100 ROWS=20 NAME=node_content><TMPL_VAR NAME=node_conte +nt></TEXTAREA> </TD> </TR> <TR><TD><INPUT TYPE="SUBMIT" NAME=action_name VALUE="<TMPL_VAR NAME=ac +tion_name>"></TD></TR> <TD><INPUT TYPE="RESET" VALUE="Reset"></TD> </TR> </TABLE> <SELECT NAME="<TMPL_VAR NAME=select_name>"> <TMPL_LOOP NAME="options"> <OPTION><TMPL_VAR NAME="opt"></OPTION> </TMPL_LOOP> </SELECT> </FORM> </TMPL_LOOP>
    UPDATE:
    Also, you should go ahead and get in the habit of using lower case for HTML tags. This is the new standard, and it also helps to differentiate between the HTML::Template tags, should you choose to keep the upper caps. These days i find myself just using lower case for them all and dropping the NAME parameter like so:
    <html> <body> <tmpl_var foo> <tmpl_loop bar> <tmpl_var baz> <tmpl_var qux> </tmpl_loop> </body> </html>

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      This is good stuff. Using the code I have and following your HTML for the template
      $$returnArray[$index]{options} = $typesArray;
      populated the template perfectly.

      Thanks, jeffa!

      If things get any worse, I'll have to ask you to stop helping me.

Re: TMPL_LOOP within a TMPL_LOOP
by samtregar (Abbot) on Apr 30, 2002 at 03:21 UTC
      Ya know ... this really is a smart way to do it. Thanks for bringing it up. Personally, i don't think this violates the golden rule of separation because a <select> is a <select> is a <select>, and they can be a real pain to create with <tmpl_loop>'s. samtregar++ :)

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)