How to add a vmethod to template toolkit when using Dancer?
If there isn't a way, how can I add a function /how to execute a ref to function which is added to the tokens/?
To add a custom vmethod to TT in Dancer requires a bit of messing with the direct TT package variables. I do wish that the Dancer::Template object provide access to the underlying template object.
Here is snippet that could go in a Dancer route:
package mydancerapp;
use Dancer qw(:syntax);
# make sure TT module is loaded since Dancer loads it later in the request cycle
use Template::Stash;
# create list op vmethod, sorry its pretty trivial
$Template::Stash::LIST_OPS->{ uc_first } = sub {
my $list = shift;
return [ map { ucfirst } @$list ];
);
It is probably best to move this into its own module mydancerapp::TT
or mydancerapp::TT::VMethods
and then load it in your main application class.
Then you can use it in your templates like:
# in route
get '/' => sub {
template 'index', { veggies => [ qw( radishes lettuce beans squash )] };
};
# in template: views/index.tt
<p>[% veggies.uc_first.join(',') %]</p>
If it went well then you should see: Radishes,Lettuce,Beans,Squash
in your output. :)
I'm not sure about adding a vmethod, but I think the second thing can be done like this:
hook 'before_template' => sub {
my $tokens = shift;
$tokens->{myfunction} = sub { ... }; # OR ...
$tokens->{otherfunction} = \&other_func;
};
In Dancer2, you can do this:
hook before => sub {
my ( $app ) = @_;
$app->template_engine->engine->context->define_vmethod( 'list' => 'uc_first' => sub {
my $list = shift;
return [ map { ucfirst } @$list ];
});
};