Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

(jeffa) Re: Structure for nested html::template loops

by jeffa (Bishop)
on Jun 02, 2002 at 01:27 UTC ( #170962=note: print w/replies, xml ) Need Help??

in reply to building nested data structure / Structure for nested html::template loops

Here is my take on the problem, but first i gotta share this with you. Take a list of numbers and break them up into a two dimensional array, each inner array contains, say 4 elements. Here was my first naive try:
use strict; use Data::Dumper; my $i = 0; my (@tab,@row); for (0..10) { unless ($i % 4 or $i == 0) { push @tab,[@row]; @row = (); } push @row,$_; $i++; } push @tab,[@row]; print Dumper \@tab;
In a nutshell, we iterate through the list. Unless we have reached the 4th element, we store that element in another transitory list. If we have reached the 4th element, we store that list into our outer array. This was the logic i started with trying to solve your problem. It is rather inelegant as i have to push that final transitory array after the loop is finished - and that's what bit me when i applied it to this HTML::Template problem.

Now, consider this approach instead:

use strict; use Data::Dumper; my ($i,$j) = (0,0); my $tab; for (0..10) { push @{$tab->[$j]},$_; $j++ unless ++$i % 4; } print Dumper $tab;
Wow, so much simpler. This takes advantage of Perl's auto-vivification abilities. Instead of depending upon different states, we just do it - and we don't have to worry about clearing a transitory array, but we do have an extra counter for iteration. I'll take that extra counter for ease of programming.

So, here is my solution to this larger problem at hand. You will have to make modifications to suite your needs, but this should show you how to do it. I ran this code from my public_html directory on my images directory. That directory contained 3 subdirs with a different numbers of images in each one. I also bundled the template file into the code via the DATA filehandle.

use strict; use HTML::Template; use File::Basename; my $row_limit = 5; my $image_dir = 'images'; my %ok_ext = map { $_ => 1 } qw(jpg gif png); my $data = do {local $/; <DATA>}; my $template = HTML::Template->new( scalarref => \$data, ); my @dir_row; while(my $dir = <$image_dir/*>) { next unless -d $dir; my ($i,$j) = (0,0); my $dir_row = {dir => $dir}; while (my $full = <$dir/*>) { my ($file,$ext) = (fileparse($full,keys %ok_ext))[0,2]; next unless $ok_ext{$ext}; push @{$dir_row->{file_row}->[$j]->{images}}, { filename => $full, alt => $file }; $j++ unless ++$i % $row_limit; } push @dir_row, $dir_row; } $template->param( title => 'Images', dir_row => \@dir_row, ); print $template->output; __DATA__ <html> <head> <title><tmpl_var title></title> </head> <body> <center> <tmpl_loop dir_row> <table border="1"> <caption><tmpl_var dir></caption> <tmpl_loop file_row> <tr> <tmpl_loop images> <td><img src="<tmpl_var filename>" alt="<tmpl_var alt>"> </td> </tmpl_loop> </tr> </tmpl_loop> </tmpl_loop> </table> </center> </body> </html>


(the triplet paradiddle with high-hat)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://170962]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2017-04-29 14:45 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (532 votes). Check out past polls.