Re: [htmltmpl] enhancements to H::T
Brought to you by:
samtregar
From: Joel <htm...@jo...> - 2003-12-10 16:50:13
|
>At 05:55 PM 12/10/03 +1100, Mathew Robertson wrote: >> >>In a template you may do something like: >> >><TMPL_IF user> >> <TMPL_IF user.name> >> <TMPL_VAR user.name.first> <TMPL_VAR user.name.last> >> </TMPL_IF> >> <TMPL_IF user.address> >> <TMPL_VAR user.address.street> >> <TMPL_VAR user.address.town> >> </TMPL_IF> >></TMPL_IF> >> >> >>Normally your code would look something like: >> >>if (length $user->name->first or $user->name->last ) { >> $tmpl->param ('user' => 1); >> $tmpl->param ('user.name' => 1); >> $tmpl->param ('user.name.first' => $user->name->first ); >> $tmpl->param ('user.name.last' => $user->name->last ); >>} >>if (length $user->address->street or $user->address->town) { >> $tmpl->param ('user' => 1); >> $tmpl->param ('user.address' => 1); >> $tmpl->param ('user.address.street' => $user->address->street); >> $tmpl->param ('user.address.town' => $user->address->town); >>} >> >> >>With the 'structure_vars' support you can do this: >> >>$tmpl->param( 'user.name.first' = $user->name->first ); >>$tmpl->param( 'user.name.last' = $user->name->last ); >>$tmpl->param( 'user.address.street' = $user->address->street ); >>$tmpl->param( 'user.address.town' = $user->address->town ); > >Actually, you'd just do this: > >$tmpl->param( user => $user ); > >And H::T would take care of calling the necessary methods for you. This is an easy workaround with a lovely little recursive function to traverse your hashref structure. (This is a real example, try it for yourself. Although I admit that one line of it is questionable, but it needs to know if a reference is a scalar or a hash, otherwise errors abound.) test.pl -- The code ------------------- #!/usr/bin/perl -w use strict; use HTML::Template; my $user = {name => {first => 'John', last => 'Doe'}, address => {street => '123 Main St', city => 'Washington', state => 'DC'}}; my $tmpl = HTML::Template->new(filename => 'test.txt', die_on_bad_params => 0); $tmpl->param(user => 1); &populate($tmpl, $user, 'user'); print $tmpl->output(); 1; sub populate { my $tmpl = shift; my $struct = shift; my $curr = shift; foreach (keys %$struct) { $tmpl->param("$curr.$_" => 1); if ($struct->{$_} =~ 'HASH') { &populate($tmpl, $struct->{$_}, "$curr.$_"); } else { $tmpl->param("$curr.$_" => $struct->{$_}); } } } test.txt -- The Template ------------------------ <TMPL_IF user> <TMPL_IF user.name> FName: <TMPL_VAR user.name.first> Lname: <TMPL_VAR user.name.last> </TMPL_IF> <TMPL_IF user.address> Street: <TMPL_VAR user.address.street> City: <TMPL_VAR user.address.city> State: <TMPL_VAR user.address.state> </TMPL_IF> </TMPL_IF> And if I remember correctly, Perl would allow you to "add" your own function to do this in HTML::Template at runtime. Example: sub HTML::Template::foo { return "foobar\n"; } my $template = HTML::Template->new(filename => 'blah'); print $template->foo; So technically, you could add a new function HTML::Template::structure_param that would do all the ugliness when called with: (assuming $user is a hashref) $tmpl->structure_param(user => $user); I love Perl. --Joel |