APM: Framework help: Can HTML::Template do this? If not, what CPAN module can?

Mike South msouth at gmail.com
Fri Sep 9 20:11:04 PDT 2005


If you want something that can do everything HTML::Template does, but
also anything else you could possibly want, look at Template Toolkit.

I have used both fairly extensively, and sooner or later you are going
to run into a limitation with HTML::Template that you can't easily get
around.  Template Toolkit is very powerful and highly extensible and
is unlikely to ever run out of power for what you want to do.

If you're just starting fresh with a new project, I would recommend
going with Template Toolkit from the beginning so that you don't end
up having to rewrite all your templates later when your application's
need move out beyond what HTML::Template can do.

Just to give you a couple of examples:

In HTML::Template you can do a <tmpl_if foo>, but it only tells you if
foo is true or false.  What if you want <tmpl_if foo='blah'>?  What if
you later realize that everything would be much easier if you could do
<tmpl_if foo =~/bla(h|bber)/>?  Template Toolkit can do an if with
equals or matches (not with the exact syntax I showed there, but it
can do it).

One of the nicest things about Template Toolkit is that you can pass
in structured data and access it from the template.  If you have an
array of hashes like this:

$folks = [
{
name => 'bob',
fruit =>'kiwi',
friends => [qw/ sally jessie raphael/],
},

{
name => 'sally',
fruit => 'kumquat',
friends =>[],
}
];

and you pass that in to a template as 'folks',  you can have a loop like this:

[% FOREACH person = folks %]
[% person.name %] likes [% person.fruit %]
[% FOREACH friend = person.friends %]
[% IF loop.first %][% person.name %] is a friend of: [%END%]
[% friend %]
[% END %]
[% END %]

Here's a complete script.  It's a little harder to get going with
Template Toolkit for the first time, but it's worth it.
#!/usr/bin/perl  -w
use strict;
use Template;

my $folks = [
   {
       name => 'bob',
       fruit =>'kiwi',
       friends => [qw/ sally jessie raphael/],
   },
   {
       name => 'sally',
       fruit => 'kumquat',
       friends =>[],
   },
   {
       name => 'misery',
       fruit => 'company',
       friends =>[qw/ avarice sloth /],
   },
   {
       name => 'batman',
       fruit => 'robin',
       friends =>[qw/ catwoman /],
   },
];

#and you pass that in to a template as 'folks',  you can have a loop like this:

my $template = Template->new();

my $output;

$template->process(\*DATA, {folks=>$folks}, \$output) || die $template->error;

print $output;

__DATA__
[%- FOREACH person = folks %]
======================

   [%- person.name %] likes [% person.fruit %]
       [%- FOREACH friend = person.friends -%]
           [%- IF loop.first %]
[% person.name %] is a friend of:[% END -%]
               [%- IF loop.last && person.friends.size > 1  %] and[%
END %] [% friend %][% IF not loop.last and person.friends.size > 2
%],[% END -%]

       [%- END -%]
   [%- IF loop.last  %]
======================
   [%- END -%]

[%- END  %]

HTML::Template is evolving, and I have done a lot of useful work with
it, I'm not trying to dis it in the least.  I just think it sounds
like you are already bumping around the edges of what it can do, and
you might be well advised to give Template Toolkit a try.

mike

p.s. I also gzipped the file and attached it to avoid wrapping issues.
 Here is what the output is supposed to look like:

[msouth at localhost ~]$ perl apm.pl

======================
bob likes kiwi
bob is a friend of: sally, jessie, and raphael
======================
sally likes kumquat
======================
misery likes company
misery is a friend of: avarice and sloth
======================
batman likes robin
batman is a friend of: catwoman
======================


On 9/9/05, Bill Raty <bill.raty at gmail.com> wrote:
> I've found another interesting inflection point is the 'associate' parameter
> given to the template constructor.   Associate tells the template that
> another object has a 'param' method that acts like the one in CGI.pm: called
> with args its a setter, called without args in a list context returns a list
> of parameter names that are provided by the object.  Thus the code using the
> template can do some passive relection of templates by making a crafty
> 'param' method.
>  
>  I'll send out examples if I'm able to cobble up anything promising.
>  
>  Meanwhile, thanks again Austin Mongers!
>  
>  -Bill
> 
> On 9/8/05, Bill Raty <bill.raty at gmail.com> wrote:
> > Thanks Wayne.
> > 
> > Aha!  I may get away with it using the 'filters'.  Also the special loop
> vars look promising:
> > 
> > 
> > <TMPL_LOOP NAME="FOO">
> > <TMPL_IF NAME="__first__">
> > This only outputs on the first pass.
> > </TMPL_IF>
> > 
> > <TMPL_IF NAME="__odd__">
> > 
> > 
> > This outputs every other pass, on the odd passes.
> > </TMPL_IF>
> > 
> > <TMPL_UNLESS NAME="__odd__">
> > This outputs every other pass, on the even passes.
> > </TMPL_IF>
> > 
> > 
> > 
> > <TMPL_IF NAME="__inner__">
> > This outputs on passes that are neither first nor last.
> > </TMPL_IF>
> > 
> > This is pass number <TMPL_VAR NAME="__counter__">.
> > 
> > 
> > 
> > <TMPL_IF NAME="__last__">
> > This only outputs on the last pass.
> > <TMPL_IF>
> > 
> > 
> > </TMPL_LOOP>
> > 
> > It still seems to require that the template writer to know too much about
> inclusions or adhere to a convention.
> > 
> > -Bill
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > 
> > On 9/8/05, Wayne Walker <wwalker at bybent.com > wrote:
> > > You can do this with TMPL_IF and TMPL_INCLUDE
> > > <head>
> > >   <tmpl_if name=calendar_present>
> > >     <tmpl_include name="path/to/cal.js">
> > >   </tmpl_if>
> > > </head>
> > > <body>
> > > stuff
> > >   <tmpl_if name=calendar_present>
> > >     <div .....>
> > >   </tmpl_if>
> > > </body>
> > > 
> > > This requires that you set calendar_present=1 in the calling program.
> > > 
> > > Since I'm not sure what decides if the calendar ends up in the 
> > > container, I can't guess further
> > > 
> > > 
> > > On Thu, Sep 08, 2005 at 04:58:52PM -0500, Bill Raty wrote:
> > > >
> > > >    I'm trying not to reinvent the wheel, but I'm having difficulty
> determining
> > > >    if the wheel I'm needing has been invented. 
> > > >
> > > >    I've looked at HTML::Template POD, and I get the basic concept.  In
> my
> > > >    ignorance I'm failing to see how I can apply it to my problem, and
> ifthere
> > > >    are other CPAN modules that are better suited to my task. 
> > > >
> > > >    I want to have a DWIMy page component system so that page controls
> can be
> > > >    called out and "Do The Right Thing".  Example:
> > > >
> > > >    I  have  a  calendar  input  widget set that 
> requires pieces of HTML,
> > > >    JavaScript, and CSS, which need to be exposed in the container
> page; a
> > > >    script tag in the "head",  a 'div' that needs to appear early on
> inside the
> > > >    "body" tag, and the 'input' tag that has event handlers that usethe
> earlier 
> > > >    script tag.
> > > >    I'd like a system that abstract the container page, that lets me
> develop the
> > > >    calendar control component as if it were the containing page, but
> when
> > > >    added/included/embedded in the container page the system smartly
> places the 
> > > >    control component elements in the correct part of the containing
> page.  The
> > > >    clincher is the second add of the calendar widget doesn't duplicate
> the
> > > >    'script' and 'div' tags, but only interjects the 'input' tag for
> the second 
> > > >    control.
> > > 
> > > > _______________________________________________
> > > > Austin mailing list
> > > > Austin at pm.org 
> > > > http://mail.pm.org/mailman/listinfo/austin
> > > 
> > > --
> > > 
> > > Wayne Walker
> > > 
> > > wwalker at bybent.com                    Do you use Linux?!
> > > http://www.bybent.com                 Get Counted! 
> http://counter.li.org/
> > > Perl - http://www.perl.org/           Perl User Groups -
> http://www.pm.org/ 
> > > Jabber:  wwalker at jabber.gnumber.com   AIM:     lwwalkerbybent
> > > IRC:     wwalker on freenode.net
> > > _______________________________________________ 
> > > Austin mailing list
> > > Austin at pm.org
> > > http://mail.pm.org/mailman/listinfo/austin
> > > 
> > 
> > 
> 
>  
> _______________________________________________
> Austin mailing list
> Austin at pm.org
> http://mail.pm.org/mailman/listinfo/austin
> 
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: apm.pl.gz
Type: application/x-gzip
Size: 502 bytes
Desc: not available
Url : http://mail.pm.org/pipermail/austin/attachments/20050910/a20a4312/apm.pl.gz


More information about the Austin mailing list