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

Inspired (outspired?) by Ovid's recent tutorial, I'm converting a handful of CGI.pm web pages to use HTML::Template.

So far, so good, except for hashes of URLs and text titles.   btrott, merlyn, and jcwren helped me get that going for CGI.pm a while back using map.   But now I'm at a loss for how to apply that to HTML::Template, even after reading the tutorial and modules docs.   Looks like it would involve <TEMPL_LOOP>, but my synapses just aren't synapping well today.

Thanks in advance for any direction, suggestions, or examples.
    cheers,
    Don
    striving for Perl Adept
    (it's pronounced "why-bick")

Hmmm... hope this <READMORE> tag works...


Here's a simplification of existing CGI.pm-only page (template-not.pl)

#!/usr/bin/perl -wT use strict; use CGI::Pretty qw(:all); use CGI::Carp qw(fatalsToBrowser); # during debugging #use CGI::Carp; # after debugging use Time::localtime; use File::stat; my $dtd = '-//W3C//DTD HTML 4.0 Transitional//EN'; my $servname = $ENV{'SERVER_NAME'}; my $file = 'template-not.pl'; my $filemod = ctime(stat($file)-> mtime); my %urlhash = ( b('home') => '/', b('sitedocs') => '/sitedocs.pl', b('switches') => '/switches.pl', b('netdocs') => '/netdocs.pl', ); print header(-type => 'text/html'), start_html( -title => "$servname", -dtd => "$dtd", ); print ( map { a({href => $urlhash{$_}}, $_), br } sort keys %urlhash ); print ( p, 'code update', ($filemod), end_html );

Now here's simplification of my HTML::Template code (template.pl)
#!/usr/bin/perl -wT use strict; use HTML::Template; use HTML::Entities; use CGI::Pretty qw(:all); use CGI::Carp qw(fatalsToBrowser); # during debugging #use CGI::Carp; # after debugging complete use Time::localtime; use File::stat; my $template = HTML::Template->new(filename => 'template.tmpl'); my $code = 'template.pl'; my $tmpl = 'template.tmpl'; $template-> param( CODEMOD => ctime(stat($code)-> mtime), TMPLMOD => ctime(stat($tmpl) -> mtime), SERVNAME => $ENV{'SERVER_NAME'}, ); # hash of URLs and text labels goes here somehow print header, $template->output;

And here's my simplified HTML::Template template (template.tmpl)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE><!-- TMPL_VAR NAME=SERVNAME --></TITLE> </HEAD> <BODY> TMP_LOOP(?) of %urlhash goes here <P> Code update <!-- TMPL_VAR NAME=CODEMOD --> <BR> Template update <!-- TMPL_VAR NAME=TMPLMOD --> </BODY> </HTML>

Replies are listed 'Best First'.
Re: HTML::Template and hash o' links+labels
by repson (Chaplain) on Dec 21, 2000 at 06:27 UTC
    Here's my usual method (important parts only):
    my %urlhash = ( b('home') => '/', b('sitedocs') => '/sitedocs.pl', b('switches') => '/switches.pl', b('netdocs') => '/netdocs.pl', ); my @urls; while (my ($name,$url) = each %urlhash) { push @urls, { NAME => $name, URL => $url }; } $template->param( URLLOOP => \@urls ); __END__ <tmpl_loop name="urlloop"> <a href="<tmpl_var name="url">"> <tmpl_var name="name"> </a> </tmpl_loop>
      Thanks, repson - is just what I was looking for.   8^)
      Working code + markup below.
          cheers,
          Don
          striving for Perl Adept
          (it's pronounced "why-bick")


      (template.pl)

      #!/usr/bin/perl -wT use strict; use HTML::Template; use HTML::Entities; use CGI qw(:all); # use CGI::Pretty qw(:all); use CGI::Carp qw(fatalsToBrowser); # debugging only - for production +"use CGI::Carp;" use Time::localtime; use File::stat; use vars qw(@urlsA @urlsB); my $code = 'template.pl'; my $tmpl = 'template.tmpl'; my $template = HTML::Template->new(filename => "$tmpl"); my %urlhashA = ( 'home' => '/', 'sitedocs' => '/doc/', ); my %urlhashB = ( 'Perl Monks' => 'http://www.perlmonks.org/', 'CPAN' => 'http://search.cpan.org/', 'Google' => 'http://www.google.com/', 'Cisco' => 'http://www.cisco.com/', ); while (my ($name,$url) = each %urlhashA) { push @urlsA, { nameA => $name, urlA => $url, } } $template->param(urlloopA => \@urlsA); while (my ($name,$url) = each %urlhashB) { push @urlsB, { nameB => $name, urlB => $url, } } $template->param(urlloopB => \@urlsB); $template-> param( codemod => ctime(stat($code)-> mtime), tmplmod => ctime(stat($tmpl) -> mtime), servname => $ENV{'SERVER_NAME'}, ); print header, $template->output;


      (template.tmpl)

      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE><!-- tmpl_var name=servname --></TITLE> </HEAD> <BODY> <!-- tmpl_loop name="urlloopA" --> <A HREF="<!-- tmpl_var name="urlA" -->"> <B><!-- tmpl_var name="nameA" --></B> </A> &nbsp;&nbsp;&nbsp; <!-- /tmpl_loop --> <P> <!-- tmpl_loop name="urlloopB" --> <A HREF="<!-- tmpl_var name="urlB" -->"> <!-- tmpl_var name="nameB" --> </A> <BR> <!-- /tmpl_loop --> <P> Code update <!-- tmpl_var name=codemod --> <BR> Template update <!-- tmpl_var name=tmplmod --> </BODY> </HTML>
      I've been using HTML::Template on the project I'm currently working on. This is exactly the method I use and it has worked like a charm.

      /\/\averick

Re: HTML::Template and hash o' links+labels
by ichimunki (Priest) on Dec 21, 2000 at 05:53 UTC
    I have not done this, but the directions seem to indicate something like:
    my %hash = ( 'Perl Monks' => 'www.perlmonks.org', 'Gossip and Innuendo' => 'www.salon.com', 'Free Software' => 'www.gnu.org' ); # we need parallel lists for each of the variables my @label_list; my @url_list; foreach my $label ( keys %hash ) { push( @label_list, $label ); push( @url_list, $hash{$label} ); } my @loop_data = (); while (@label_list) { my %row_data = {}; $row_data{'LABEL'} = shift @label_list; $row_data{'URL'} = shift @url_list; push( @loop_data, \%row_data ); } $template->param(THIS_LOOP => \@loop_data); ========== then in the template: <TMPL_LOOP NAME="THIS_LOOP"> Hotlink: <A HREF="<TMPL_VAR NAME="URL">"><TMPL_VAR NAME="LABEL"></ +A><P> </TMPL_LOOP>
    But this is a guess. I'd do a Data::Dumper print Dumper( @loop_data ) to get a feel for what this has done. :)

    Update: Put while loop around the shift bit, based on repson's input. I overlooked the loop around this section of the sample code in the POD for this module.

      Don't you want a loop around this block
      # while (@label_list) { $row_data{'LABEL'} = shift @label_list; $row_data{'URL'} = shift @url_list; push( @loop_data, \%rowdata ); # }
      Though I think it is easier to construct @loop_data during your loop over then hash keys instead of creating two lists in the loop and then looping over their elements.
Re: HTML::Template and hash o' links+labels (sorted links 8^)
by ybiC (Prior) on Dec 21, 2000 at 22:20 UTC
    repson's answer got me to a working script.   8^)   Now I'm looking to sort the links alphanumericly on the generated page.

    I've tinkered with Tie::IxHash, and perused perlfunc:sort.   Suggestions for a good approach, before I start some ugly kludge?

    Update: tieing the hash seems to do the trick.   Rather than alphanumeric sort, it simply retains the insertion order.   8^)
        cheers,
        Don
        striving for Perl Adept
        (it's pronounced "why-bick")