Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

HTML::Template: Howto make a inner/outer loop?

by grath (Initiate)
on Apr 05, 2004 at 19:25 UTC ( [id://342716]=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

Short and to the point.

1. I'm using this script to dump information from a database (and it works, yes :).

dump.pl
-----------------------------------------------------------------
#!/usr/bin/perl use CGI qw/:standard :html3/; use CGI::Carp qw(fatalsToBrowser); use DBI; use DBD::mysql; my $DBName = "test"; my $DBHost = "localhost"; my $DBUser = "test"; my $DBPass = "dev"; my $DBType = "mysql"; my $DBPort = "3306"; sub db_connect { my ($result); $result = DBI->connect( "DBI:$DBType:database=$DBName;host=$DBHost +", "$DBUser", "$DBPass", { 'RaiseError' => 0 } ) || &error("Unable to + connect to database"); return $result; } sub db_query { my ($result, $query); $query = $_[0]; $result = &db_connect->prepare($query) || &error("Unable to query +the database"); $result->execute(); return $result; } # outer loop my $query1 = &db_query("SELECT id, title FROM sections"); while (my $rows1 = $query1->fetchrow_hashref()) { print "Section: " . $rows1->{title}."\n"; my $sectionid = $rows1->{id}; # inner loop my $query2 = &db_query("SELECT title FROM pages WHERE sectioni +d = $sectionid"); while (my $rows2 = $query2->fetchrow_hashref()) { print "-> Page: " . $rows2->{title}."\n"; } }

-----------------------------------------------------------------

2. Since I have started using HTML::Template on my webpage, I have to port this script to get use of a template. The template looks something like this:

dump.html
-----------------------------------------------------------------
<TMPL_LOOP NAME="SECTIONS"> Section: <TMPL_VAR NAME="TITLE"><br> <TMPL_LOOP NAME="PAGES"> -> Page: <TMPL_VAR NAME="TITLE"><br> </TMPL_LOOP> </TMPL_LOOP>

3. I have tried to make a new script for HTML::Template, but I can't get the script working with the template because of the outer/inner loop.

Somebody out there with a solution? :-)

Regards, Eivind Hestnes

Replies are listed 'Best First'.
Re: HTML::Template: Howto make a inner/outer loop?
by jeffa (Bishop) on Apr 05, 2004 at 20:25 UTC
    I recommend you first get rid of that db_query function ... DBI has plenty of abstraction, i don't understand why folks just can't RTFM a bit more ... Anyways :) Try this untested snippet of code:
    my $dbh = DBI->connect( qw(DBI:mysql:database:host user pass), #substitute your values here {RaiseError => 1 }, ); my $sections = $dbh->selectall_arrayref(' SELECT id, title FROM sections ',{Slice => {}}); for my $section (@$sections) { my $pages = $dbh->selectall_arrayref(' SELECT SELECT title FROM pages WHERE sectionid = ? ',{Slice => {}}, $section->{id}); $section->{pages} = $pages; } my $tmpl = HTML::Template->new(filehandle => \*DATA); $tmpl->param(sections => $sections); print $tmpl->output; __DATA__ <ul> <tmpl_loop sections> <li>Section: <tmpl_var title> <ul> <tmpl_loop pages> <li>Page: <tmpl_var title></li> </tmpl_loop> </ul> </tmpl_loop> </ul>

    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)
    
Re: HTML::Template: Howto make a inner/outer loop?
by gryphon (Abbot) on Apr 05, 2004 at 20:18 UTC

    Greetings grath,

    I worship HTML::Template these days, but one of my early learning curve issues was figuring out nested loops. (This was before I actually RTFMed HTML::Template instead of just skimming, though.) Just remember that everything is a hash, and loops are just a bunch (i.e. array) of hashes. When you have a nested loop, it's just an array of hashes that's the value of a key that's part of the outer loop.

    The following code is untested and was pulled from your legacy script and modified. This should give you a place from which to get started.

    my $query1 = &db_query("SELECT id, title FROM sections"); my @sections = (); while (my $rows1 = $query1->fetchrow_hashref()) { my $sectionid = $rows1->{id}; my $query2 = &db_query("SELECT title FROM pages WHERE sectionid = $s +ectionid"); my @pages = (); while (my $rows2 = $query2->fetchrow_hashref()) { push @pages, $rows2; } push @sections, { pages => \@pages }; } $template->param(sections => \@sections);

    I hope this helps. Try using Dump::Dumper to see the created data structure before sending it to HTML::Template. Actually seeing the data structure has helped me on many occations. Also, your legacy script doesn't use strict or use warnings. I recommend you put those in there.

    UPDATE: Use jeffa's code from his post. It's far better than mine because he rewrote the database interface using more standard DBI syntax. Use my code above only as a learning tool to map to your original script.

    gryphon
    code('Perl') || die;

Re: HTML::Template: Howto make a inner/outer loop?
by matija (Priest) on Apr 05, 2004 at 20:32 UTC
    The code should look something like this:
    my @outer; while (my $rows1 = $query1->fetchrow_hashref()) { my $query2 = &db_query("SELECT title FROM pages WHERE sectionid = $ +sectionid"); $inner=[]; # you need a NEW array for each loop, not just an empty + array while (my $rows2 = $query2->fetchrow_hashref()) { push(@$inner,{TITLE=>$rows2->{title}); } push(@outer,{ TITLE=>$rows1->{title}, PAGES=>$inner; }); } $template->param(sections=>\@outer);
    The most common mistake with this problem (it bites everybody at least once) is assigning an empty array instead of an empty array reference in the inner loop. If you make that mistake, the values for all the inner loops end up the same.
Re: HTML::Template: Howto make a inner/outer loop?
by dragonchild (Archbishop) on Apr 05, 2004 at 19:42 UTC
    What is the script that isn't working in #3? My mind-reading helmet is in the shop for repairs.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

Re: HTML::Template: Howto make a inner/outer loop?
by Elijah (Hermit) on Apr 05, 2004 at 19:30 UTC
    What error indications are you getting? At first glance I cannot really tell you at what instance your error is being generated or unhandled.

    www.perlskripts.com

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://342716]
Approved by kutsu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2024-04-24 06:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found