in reply to Got those HTML::Template and subroutine blues

How about something like this?
my %tmpl_hash = ( urlloopA => { 'Home' => '/', 'Icons' => '/icons/', 'Sitedocs' => '/doc/', }, urlloopB => { 'Cisco' => 'http://www.cisco.com/', 'CPAN' => 'http://search.cpan.org/', 'Google' => 'http://www.google.com/', 'Perl Monks' => 'http://www.perlmonks.org/', }, ); for my $loop (keys %tmpl_hash) { my @vars; while (my($name, $url) = each %{$tmpl_hash{$loop}}) { push @vars, { name => $name, url => $url }; } $template->param($loop, [ @vars ]); }
with a corresponding change to your template:
<!-- tmpl_loop name="urlloopA" --> <A HREF="<!-- tmpl_var name="url" -->"> <B><!-- tmpl_var name="name" --></B> </A> &nbsp;&nbsp;&nbsp; <!-- /tmpl_loop --> <P> <!-- tmpl_loop name="urlloopB" --> <A HREF="<!-- tmpl_var name="url" -->"> <!-- tmpl_var name="name" --> </A> <BR> <!-- /tmpl_loop -->
The separate hashes become a hash of hashes and the separate loops become a nested loop.

According to the HTML::Template docs, a TMPL_LOOP has its own scope; reusing the same variable names in different loops should work just fine.

Replies are listed 'Best First'.
Re: (2) Got those HTML::Template and subroutine blues (chipmunk++)
by ybiC (Prior) on Dec 23, 2000 at 00:11 UTC
    That works like a charm.   chipmunk - you are wise beyond your size.   {grin}

    I oversimplified my script for the post, though.   Was using Tie::IxHash for insertion-order retrieval of hash elements.

    use Tie::IxHash; tie my %urlhashA, "Tie::IxHash"; %urlhashA = ( 'blah' => 'URL', 'bleh' => 'notherURL', 'bloo' => 'ananotherURL', );
    I didn't spot anything in perldoc IxHash.pm about using it with hash o' hashes.  
    tie my %tmpl_hash, "Tie::IxHash"; did nothing noticeable.  
    Attempts to tie urlloop failed as well.

    Is this do-able?

    Update: chipmunk's post below puts a glide in my stride.   8^)   chipmunk++.
        cheers,
        Don
        striving for Perl Adept
        (it's pronounced "why-bick")

      Ah, that makes sense, because you want the HTML output to be in the right order. The tricky thing is that the outer hash and each of the inner hashes must be tied to Tie::IxHash... I'm trying to imagine the code for that, and it's not coming out very pretty. :)

      So, I'll propose an array of arrays solution instead.

      my @tmpl_array = ( urlloopA => [ 'Home' => '/', 'Icons' => '/icons/', 'Sitedocs' => '/doc/', ], urlloopB => [ 'Cisco' => 'http://www.cisco.com/', 'CPAN' => 'http://search.cpan.org/', 'Google' => 'http://www.google.com/', 'Perl Monks' => 'http://www.perlmonks.org/', ], ); for (my $i = 0; $i < $#tmpl_array; $i+=2) { my($loop, $aref) = @tmpl_array[$i, $i+1]; my @vars; for (my $j = 0; $j < $#{$aref}; $j+=2) { my($name, $url) = @{$aref}[$j, $j+1]; push @vars, { name => $name, url => $url }; } $template->param($loop, [ @vars ]); }
      We're sort of simulating the ordered hashes, by having paired elements in each of the arrays. This works because we don't actually need any hash key lookups!

      Update: This code would be used with the same updated template as the hash of hashes suggestion in my earlier reply.

        Personally I avoid using the C-style for, since I find it harder to see exactly what what it is doing at a glance. I also avoid loop indexes as they aren't very perlish. This is another way to do it, but it destroys the arrays, which may or may not be acceptable.
        while ( @tmpl_array ) { my ($loop, $aref) = splice @tmpl_array,0,2; my @vars; while (@$aref) { my ($name, $url) = splice @$aref,0,2; push @vars, { name => $name, url => $url }; } $tmpl->param($loop, \@vars; }