1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
package Text::Handlebars;
use strict;
use warnings;
use base 'Text::Xslate';
use Scalar::Util 'weaken';
use Try::Tiny;
sub default_functions {
my $class = shift;
return {
%{ $class->SUPER::default_functions(@_) },
'(is_array)' => sub {
my ($val) = @_;
return ref($val) && ref($val) eq 'ARRAY';
},
'(is_empty_array)' => sub {
my ($val) = @_;
return @$val == 0;
},
'(make_array)' => sub {
my ($length) = @_;
return [(undef) x $length];
},
'(is_code)' => sub {
my ($val) = @_;
return ref($val) && ref($val) eq 'CODE';
},
'(new_vars_for)' => sub {
my ($vars, $value, $i) = @_;
if (my $ref = ref($value)) {
if (defined $ref && $ref eq 'ARRAY') {
die "no iterator cycle provided?"
unless defined $i;
$value = ref($value->[$i])
? $value->[$i]
: { '.' => $value->[$i] };
$ref = ref($value);
}
return $vars unless $ref && $ref eq 'HASH';
weaken(my $vars_copy = $vars);
return {
%$vars,
%$value,
'..' => $vars_copy,
};
}
else {
return $vars;
}
},
};
}
sub options {
my $class = shift;
my $options = $class->SUPER::options(@_);
$options->{compiler} = 'Text::Handlebars::Compiler';
return $options;
}
sub _register_builtin_methods {
my $self = shift;
my ($funcs) = @_;
weaken(my $weakself = $self);
$funcs->{'(run_code)'} = sub {
my ($code, $vars, $open_tag, $close_tag, @args) = @_;
my $to_render = $code->(@args);
$to_render = "{{= $open_tag $close_tag =}}$to_render"
if defined($open_tag) && defined($close_tag) && $close_tag ne '}}';
return $weakself->render_string($to_render, $vars);
};
$funcs->{'(find_file)'} = sub {
my ($filename) = @_;
return 1 if try { $weakself->find_file($filename); 1 };
$filename .= $weakself->{suffix};
return 1 if try { $weakself->find_file($filename); 1 };
return 0;
};
$funcs->{'(run_block_helper)'} = sub {
my ($code, $raw_text, $vars, @args) = @_;
my $recurse = sub {
my ($new_vars) = @_;
return $weakself->render_string($raw_text, $new_vars);
};
return $code->($vars, @args, { fn => $recurse });
};
}
1;
|