4

I have a currency value that I would like to format using Locale::Currency::Format however I have no idea how to format it.

Here is my output in Template Toolkit

[% amount %]

I would like this to be outputted using the following method:

currency_format('USD', amount, FMT_SYMBOL)

New to template toolkit so any help is appreciated.

KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
  • 1
    I understand this can be done in the Controller, but I'd like to know if this can be handled in the template. – KingKongFrog Dec 20 '13 at 00:49
  • Do you have [EVAL_PERL](http://search.cpan.org/~abw/Template-Toolkit-2.25/lib/Template/Manual/Directives.pod#PERL) enabled in your controller? If so, you can include raw perl in your template. – codnodder Dec 20 '13 at 03:21

3 Answers3

3

I like Dave Cross' answer, and I agree with both he and codnodder about EVAL_PERL, which I've yet to find necessary as a solution in 7 or 8 years of almost daily TT use.

Personally, I would use:

[%- USE fmt = Class('Locale::Currency::Format'); -%]

<td>[% fmt.currency_format(var1, var2, var3) %]</td>

But if I was using this all the time, I'd be tempted to write a TT plugin wrapper around it.

RET
  • 9,100
  • 1
  • 28
  • 33
2

I can't find Local::Currency::Format on CPAN, so I can't show you exactly how it works with this module. I can, however, show you the general direction you need to go in.

You have several options:

1/ Use currency_format to format the data before it is passed into the template.

my $amount = currency_format('USD', $amount, FMT_SYMBOL);
$tt->process($template_name, { amount => $amount, ... }) or die;

Then in the template you can just use [% amount %].

2/ Pass currency_format as a dynamic variable to the template.

$tt->process($template_name, {
  amount          => $amount,
  currency_format = > \&currency_format,
  ...
}) or die;

Then in the template, you can use currency_format as a function:

[% currency_format('USD', amount, FMT_SYMBOL) %]

3/ Write a real TT plugin for Local::Currency::Format.

Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • I originally had the same thoughts as you, until I saw the OP's comment about handling this exclusively within the template. Just bringing this to your attention in case you had any other thoughts on methods that work exclusively within the template, but do not need `EVAL_PERL=>1` @Dave-Cross – codnodder Dec 20 '13 at 17:34
  • 1
    My rule of thumb is that if you're reaching for EVAL_PERL, then you're doing too much in the template :-) – Dave Cross Dec 20 '13 at 18:35
  • 2
    Can't agree more @Dave-Cross – codnodder Dec 20 '13 at 23:04
1

If you have EVAL_PERL enabled in your "controller", you can use embedded perl to include the module and add a vmethod for example.

E.g.,

use strict;
use Template;

my $tt = Template->new(EVAL_PERL=>1);
my $out;
$tt->process(\*DATA, { amount => 50.34 }, \$out) or die $tt->error, "\n";
print $out;

__DATA__
[% PERL -%]
sub dollars { sprintf('$%0.02f', $_[0]); }
# or:
# use Local::Currency::Format;
# sub dollars { currency_format('USD', $_[0], FMT_SYMBOL); }
$stash->define_vmethod('scalar', 'dollars', \&dollars);
[% END -%]
The amount is [% amount.dollars %].

If you have some access to the "controller", you can add a FILTER.

use strict;
use Template;
#use Local::Currency::Format;  

my $tt = Template->new({
   #FILTERS => { 'dollars' => sub { currency_format('USD', $_[0], FMT_SYMBOL); } },
    FILTERS => { 'dollars' => sub { sprintf('$%0.02f', $_[0]); } },
});
my $out;
$tt->process(\*DATA, { amount => 50.34 }, \$out) or die $tt->error, "\n";
print $out;

__DATA__
The amount is [% amount | dollars %].

EDIT: Note that my use of sprintf to format the currency is just a placeholder. You would replace that with whatever module or method you choose.

codnodder
  • 1,674
  • 9
  • 10