[Dancer-users] Tokens and Template plugins

David Precious davidp at preshweb.co.uk
Mon Oct 4 18:14:00 CEST 2010


Hi Mike,

Sorry for the slow & rushed reply.

On Saturday 02 October 2010 20:32:52 Mike Schroeder wrote:
> I'm a new Dancer user, but I'm loving it so far.  In 4 days I was able to
> learn dancer, create plugins for accessing our existing APIs, session
> management and authentication, and port a relatively complex application.
>  Dancer is elegantly simple.  Thanks for a great architecture.  

Good to hear you're enjoying Dancer! :)

>  Now for my
> question:
> 
> Since the app I was porting used HTML::Template, I decided to use
> the Dancer::Template::HtmlTemplate module contributed by David Precious. 
> It nicely renders the tokens passed in, however I believe HTML::Template
> expects a Hash Ref made up of either scalars or of Array of Hash -
> something to the effect of:
[...snipped example...]

> However, Dancer::Helpers::template()  passes the settings, session, request
> and params as a Hash of Hash - making the vars inaccessible to
> HTML::Template.

Yes, HTML::Template can be a pain to work with - you're right that it doesn't 
handle a hash of hashes.

This is something that needs fixing - can you raise an issue on Github at 
http://github.com/bigpresh/Dancer-Template-HtmlTemplate/issues ?

I'm rather busy this week so probably won't have time to deal with it right 
away.

> I think there are two approaches:
> 
> 1) Dancer::Template::HtmlTemplate needs to be smart enough to fix up the
> $tokens hash to reformat those default values into something visible to
> HTML::Template - *something* like:
> 
> foreach my $kind ( qw( settings request params session ) ) {
>       foreach my $key ( keys %{ $tokens->{$kind} } ) {
>             $tokens->{$kind.'-'.$key} = delete $tokens->{$kind}->{$key};
>       }
> 
> }

Rather than hardcoding the param names to look at, I think I'd be inclined to 
have it automatically flatten any hashrefs in the params into keys in the to 
level hashref of params - so, for instance, if the params that were going to 
be passed to HTML::Template looked like:

{
    foo => 1,
    bar => {
      baz => 2,
      bletch => 3,
    }
}

it would get "flattened" into, say,:

{
    foo => 1,
    bar.baz => 2,
    bar.bletch => 3,
}

Having to do that is nasty, but it's a limitation of HTML::Template which 
doesn't let you dig into hashrefs, unlike for instance TT, where you can quite 
happily use e.g. [% foo.bar %]


> 2) an alternate solution would be to make the creation of tokens a
> subroutine that a Template plugin can expose back to Dancer as an
> alternative way of serializing the tokens for the given Template engine.
>  *something like:
> 
> $tokens ||= {};
> if (Dancer::Template->engine->can('create_default_tokens') ) {
>     $tokens = Dancer::Template->engine->create_default_tokens($tokens);
> } else {
> $tokens->{settings} = Dancer::Config->settings;
> $tokens->{request} = Dancer::SharedData->request;
> $tokens->{params} = Dancer::SharedData->request->params;
> if (setting('session')) {
> $tokens->{session} = Dancer::Session->get;
> }
> }

This might be a cleaner way, perhaps, but requires changes to Dancer's core 
just to support this single template engine; on the other hand, it means 
working around issues like this in future could be be easier.

> Assuming this *is*  a legitimate issue, which way is the preferred
> solution?

I think I'd be inclined to go with option 1; anyone else care to comment?

Cheers

Dave P

 
-- 
David Precious <davidp at preshweb.co.uk>
http://blog.preshweb.co.uk/    www.preshweb.co.uk/twitter
www.preshweb.co.uk/linkedin    www.preshweb.co.uk/facebook
www.preshweb.co.uk/identica    www.lyricsbadger.co.uk

  "Programming is like sex. One mistake and you have to support 
  it for the rest of your life". (Michael Sinz)


More information about the Dancer-users mailing list