in reply to building nested data structure / Structure for nested html::template loops
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.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;
Now, consider this approach instead:
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.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;
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>
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)
|
---|