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

Re^2: HTML::Template, pseudo trees and indention.

by maverick (Curate)
on Jan 10, 2006 at 15:42 UTC ( #522214=note: print w/ replies, xml ) Need Help??


in reply to Re: HTML::Template, pseudo trees and indention.
in thread HTML::Template, pseudo trees and indention.

quote: You can't do it within HTML::Template, period

According to whom?

#!/usr/bin/perl use strict; use HTML::Template; my $template = " <ul> <TMPL_LOOP tree> <li><TMPL_VAR value> (depth=<TMPL_VAR depth>) <TMPL_LOOP open><ul></TMPL_LOOP> <TMPL_IF close> <TMPL_LOOP close> </li></ul> <TMPL_IF __LAST__></li></TMPL_ +IF> </TMPL_LOOP> <TMPL_ELSE> <TMPL_UNLESS open> </li> </TMPL_UNLESS> </TMPL_IF> </TMPL_LOOP> </ul> "; my $tree = [ { 'value' => 'a', 'depth' => 1 }, { 'value' => 'b', 'depth' => 1 }, { 'value' => 'b1', 'depth' => 2 }, { 'value' => 'b2', 'depth' => 2 }, { 'value' => 'c', 'depth' => 1 }, { 'value' => 'c1', 'depth' => 2 }, { 'value' => 'c1.1', 'depth' => 3 }, { 'value' => 'd', 'depth' => 1 } ]; for my $i (0 .. $#$tree) { my $delta; if (defined($tree->[$i+1])) { $delta = $tree->[$i+1]->{'depth'} - $tree->[$i]->{'dep +th'}; } else { $delta = - $tree->[$i]->{'depth'}; } if ($delta > 0) { push(@{$tree->[$i]->{'open'}},{}) for (1 .. $delta); } elsif ($delta < 0) { push(@{$tree->[$i]->{'close'}},{}) for ($delta .. -1); } } my $html_template = HTML::Template->new( scalarref => \$template, loop_context_vars => 1); $html_template->param('tree' => $tree); print $html_template->output;
Produces the following html:
  • a (depth=1)
  • b (depth=1)
    • b1 (depth=2)
    • b2 (depth=2)
  • c (depth=1)
    • c1 (depth=2)
      • c1.1 (depth=3)
  • d (depth=1)

Isn't there some law of comp-sci that says that say any algorithm that can be written recusively, can also be written iteratively? er...or something to that effect.

Update: fixted sprelling erors

/\/\averick


Comment on Re^2: HTML::Template, pseudo trees and indention.
Download Code
Re^3: HTML::Template, pseudo trees and indention.
by dragonchild (Archbishop) on Jan 10, 2006 at 15:51 UTC
    *claps sardonically* I was waiting for that response. You did it with H::T, not within H::T. Your node is an excellent example of twisting the problem to suit the answer. Not only is your template nearly unreadable the first 3 times one reads it, but your code is nearly impossible to follow as well. The point wasn't to see if you could code a solution that involves H::T. The point was to see if H::T could provide a solution.

    And, yes, any recursive solution can be written iteratively. That doesn't mean that H::T can handle it any better.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      /me reads question again.

      ...only for strict definitions of "twist". He already has the tree as an array. He already has the depth of the nodes in the tree. The only thing he's missing is the not-so-magical trick of having H::T produce html to create the changes in depth. For that you need to know how much and which way the depth changes between any two nodes and then use a tmpl_loop to generate the right number of opens / closes.

      Granted the code needs comments, but impossible to follow is a stretch. jeffa figured it out sans comments in the time it took me to type this respone...can't be that bad :)

      /\/\averick

        jeffa understanding something and your average programmer understanding it are two completely different things. You see, jeffa actually has (at least) half a brain and is willing to use it. :-)

        I might have been a little harsh in my response. But, I feel that BUU's tree representation, while compact, is mostly unusable. Given a more useful tree representation (such as Tree or Tree::Simple), one is inevitably led to use one of the tools that already exist for reformatting objects of those classes (which I list in my original response). Why reinvent the wheel?


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re^3: HTML::Template, pseudo trees and indention.
by eric256 (Parson) on Jan 10, 2006 at 17:41 UTC

    Here is a bit simpler version. I'm not sure this doesn't miss some special case you where planning on though. It just makes an up or a down loop to raise or level the level as needed.

    #!/usr/bin/perl use strict; use HTML::Template; use Data::Dumper; my $template = " <ul> <TMPL_LOOP tree> <li><TMPL_VAR value> (depth=<TMPL_VAR depth>) <TMPL_LOOP up><ul></TMPL_LOOP> <TMPL_LOOP down></ul></TMPL_LOOP> </li> </TMPL_LOOP> </ul> "; my $tree = [ { 'value' => 'a', 'depth' => 1 }, { 'value' => 'b', 'depth' => 1 }, { 'value' => 'b1', 'depth' => 2 }, { 'value' => 'b2', 'depth' => 2 }, { 'value' => 'c', 'depth' => 1 }, { 'value' => 'c1', 'depth' => 2 }, { 'value' => 'c1.1', 'depth' => 3 }, { 'value' => 'd', 'depth' => 1 } ]; for my $i (0 .. $#$tree) { if (defined $tree->[$i+1]) { my $diff = $tree->[$i+1]->{depth} - $tree->[$i]->{depth}; if ($diff > 0) { $tree->[$i]->{up} = [({}) x $diff]; } elsif ( $diff < 0 ) { $tree->[$i]->{down} = [({}) x -$diff]; } } } my $html_template = HTML::Template->new( scalarref => \$template, loop_context_vars => 1); $html_template->param('tree' => $tree); print $html_template->output;


    ___________
    Eric Hodges
      On first glance, the subtle difference is that mine generates all the "optional" closing "li"s. I'm actually using this to generate collapsable trees in a web based app and some of the more drain bamaged *cough* IE *cough* browsers yacked if the html wasn't "well formed".

      /\/\averick

        Ahh. didn't realize how they had to nest. Here is a slightly updated version that passes W3C validation. I assume/hope that means IE will like it.

        #!/usr/bin/perl use strict; use HTML::Template; use Data::Dumper; my $template = " <ul> <TMPL_LOOP tree> <li><TMPL_VAR value> (depth=<TMPL_VAR depth>) <TMPL_UNLESS up></li></TMPL_UNLESS> <TMPL_LOOP up><ul></TMPL_LOOP> <TMPL_LOOP down></ul></li></TMPL_LOOP> </TMPL_LOOP> </ul> "; my $tree = [ { 'value' => 'a', 'depth' => 1 }, { 'value' => 'b', 'depth' => 1 }, { 'value' => 'b1', 'depth' => 2 }, { 'value' => 'b2', 'depth' => 2 }, { 'value' => 'c', 'depth' => 1 }, { 'value' => 'c1', 'depth' => 2 }, { 'value' => 'c1.1', 'depth' => 3 }, { 'value' => 'd', 'depth' => 1 } ]; for my $i (0 .. $#$tree) { if (defined $tree->[$i+1]) { my $diff = $tree->[$i+1]->{depth} - $tree->[$i]->{depth}; if ($diff > 0) { $tree->[$i]->{up} = [({}) x $diff]; } elsif ( $diff < 0 ) { $tree->[$i]->{down} = [({}) x -$diff]; } } } my $html_template = HTML::Template->new( scalarref => \$template, loop_context_vars => 1); $html_template->param('tree' => $tree); print $html_template->output;

        ___________
        Eric Hodges

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://522214]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2014-07-12 22:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (241 votes), past polls