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

I spent an hour or two writing this up last night, it took a while for me to finally figure out exactly what I needed to do to acomplish my desires. The end result I desired was to create something involving nested nodes, much like the replies to this very node, except in a CSS compliant way that doesn't invovle table abuse. The idea I finally came up with to implement this was to nest divs, each div would have an offset of however much I wanted, that way the children would be offset by their offset + their parent offset and so on. This works beautifully. However this script was fairly complicated (atleast I thought so, etc) and I was wondering if any monks out there see any improvement or outright mistakes I made. Code follows..
First off, here is the datastructure that my %cats = $c->get_cats; gets, generated via: Dumper(\%cats);
$VAR1 = { '6' => { 'parent' => '0', 'title' => 'War3', 'id' => '6', 'descr' => 'I have no subcategories' }, '1' => { 'parent' => '0', 'children' => [ { 'parent' => '1', 'children' => [ { 'parent' => 3, 'children' => [ { 'parent' => 7, 'title' => 'main sub cat1 sub cat1 sub cat1', 'id' => '9', 'descr' => 'Wewt, more recursion of doom!' } ], 'title' => 'main sub cat1 sub cat1', 'id' => 7, 'descr' => 'Sub category for a sub category! wewt.' } ], 'title' => 'main sub cat1', 'id' => 3, 'descr' => 'This is a subcategory for the main column' }, { 'parent' => '1', 'title' => 'main sub cat2', 'id' => 4, 'descr' => 'This is the second subcategory for the main c +olumn' } ], 'title' => 'Main', 'id' => '1', 'descr' => 'This is the main category, used for all stuff that +doesn\'t fit else where.' }, '2' => { 'parent' => '0', 'children' => [ { 'parent' => '2', 'children' => [ { 'parent' => 5, 'title' => 'd2 sub cat sub cat', 'id' => 8, 'descr' => 'Yet another sub sub category' } ], 'title' => 'Diablo subcategory', 'id' => 5, 'descr' => 'A subcategory for the diablo 2 section.' } ], 'title' => 'Diablo', 'id' => '2', 'descr' => 'This is the main diablo category' } };

And here is the tmpl/Categories/per_cat.tmpl used in the creation of the $hpc html::Template object, $hpc;
<div class='category' style='position:relative; left: 5em;'> <div class='title'><tmpl_var name='title'></div> <div class='descr'><tmpl_var name='descr'></div> <tmpl_var name='children'> </div>

And finally, here is the code itself:
#!/perl/bin/perl use strict; use lib 'lib'; require HTML::Template; require Categories; my $hpc = new HTML::Template(Filename=>'tmpl/Categories/per_cat.tmpl') +; my $c = new Categories; my %cats = $c->get_cats; print "Content-type: text/html\n\n"; print "<html><head></head><body>"; for(sort keys %cats) { my @child_data; my $fhtml; if( $cats{ $_ }->{ children } ) { for( @{ $cats{ $_ }->{ children } } ) { my @children = _recurse( $_ ); my $html; for( reverse @children ) { $hpc->param ( title => $_->{ title }, descr => $_->{ descr }, children => $html, ); $html = $hpc->output; $hpc->clear_params; } $fhtml.=$html;; } } $hpc->param ( title => $cats{ $_ }->{ title }, descr => $cats{ $_ }->{ descr }, children => $fhtml, ); print $hpc->output; $hpc->clear_params; } print "</body></html>"; sub _recurse { my $child = shift; my @data; if( ref($child->{ children }) eq 'ARRAY' ) { for( @{ $_->{ children } } ) { push @data, _recurse( $_ ); } } unshift @data,$child; return @data; }
With the important bits being the for loop and the _recurse subroutine.