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@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)