3

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/?

bliof
  • 2,957
  • 2
  • 23
  • 39

3 Answers3

2

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. :)

Michael
  • 8,446
  • 4
  • 26
  • 36
Lee
  • 311
  • 2
  • 4
  • I tried something like this and it didn't work so I post this question.. Now it works ^^ – bliof Oct 20 '11 at 13:02
1

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;
};
perlpilot
  • 101
  • 2
0

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 ];
    });
};
Chad
  • 693
  • 5
  • 17