File Coverage

blib/lib/Template/Toolkit/Simple.pm
Criterion Covered Total %
statement 68 102 66.6
branch 14 34 41.1
condition 2 7 28.5
subroutine 21 26 80.7
pod 6 9 66.6
total 111 178 62.3


line stmt bran cond sub pod time code
1 4     4   2536 use strict; use warnings;
  4     4   7  
  4         160  
  4         20  
  4         5  
  4         233  
2             package Template::Toolkit::Simple;
3             our $VERSION = '0.31';
4              
5 4     4   2454 use Encode;
  4         39248  
  4         400  
6 4     4   2821 use Getopt::Long;
  4         46407  
  4         28  
7 4     4   4541 use Template;
  4         92567  
  4         205  
8 4     4   45 use Template::Constants qw( :debug );
  4         7  
  4         1087  
9 4     4   2454 use YAML::XS;
  4         11651  
  4         301  
10              
11 4     4   39 use base 'Exporter';
  4         9  
  4         1828  
12             our @EXPORT = qw(tt);
13              
14             sub tt {
15 3     3 1 139 return Template::Toolkit::Simple->new();
16             }
17              
18             my $default = {
19             data => undef,
20             config => undef,
21             output => undef,
22              
23             encoding => 'utf8',
24             include_path => undef,
25             eval_perl => 0,
26             start_tag => quotemeta('[' . '%'),
27             end_tag => quotemeta('%' . ']'),
28             tag_style => 'template',
29             pre_chomp => 0,
30             post_chomp => 0,
31             trim => 0,
32             interpolate => 0,
33             anycase => 0,
34             delimiter => ':',
35             absolute => 0,
36             relative => 0,
37             strict => 0,
38             default => undef,
39             blocks => undef,
40             auto_reset => 1,
41             recursion => 0,
42             pre_process => undef,
43             post_process => undef,
44             process_template => undef,
45             error_template => undef,
46             output_path => undef,
47             debug => 0,
48             cache_size => undef,
49             compile_ext => undef,
50             compile_dir => undef,
51             };
52              
53             my $abbreviations = {
54             data => 'd',
55             include_path => 'path|i',
56             output => 'o',
57             config => 'c',
58             };
59              
60             sub new {
61 3     3 1 35 my $class = shift;
62 3   50     104 return bless shift || {%$default}, $class;
63             }
64              
65             sub field {
66 116     116 0 145 my ($name, $value) = @_;
67             return sub {
68 6     6   6 my $self = shift;
69 6 100       31 $self->{$name} = @_ ? shift : $value;
70 6         29 return $self;
71 116         552 };
72             }
73              
74             {
75             for my $name (keys %$default) {
76             next if $name =~ /^(data|config)/;
77             my $value = $default->{$name};
78             if (defined $value) {
79             $value = 1 - $value if $value =~/^[01]$/;
80             $value = [] if $name eq 'include_path';
81             }
82 4     4   28 no strict 'refs';
  4         12  
  4         296  
83             *{__PACKAGE__ . '::' . $name} = field($name, $value);
84             }
85             }
86              
87             {
88 4     4   21 no warnings 'once';
  4         7  
  4         4946  
89             *path = \&include_path;
90             }
91              
92             sub render {
93 3     3 1 9 my $self = shift;
94 3 50       10 my $template = shift
95             or die "render method requires a template name";
96 3 50       25 if ($template =~ qr{//}) {
97 0         0 my $path;
98 0         0 ($path, $template) = split '//', $template, 2;
99 0         0 $self->include_path($path);
100             }
101 3 50       11 $self->data(shift(@_)) if @_;
102 3 50       9 $self->output(shift(@_)) if @_;
103              
104 3 50       11 if ($self->{output}) {
105 0 0       0 $self->process($template, $self->{data}, $self->{output})
106             or $self->croak;
107 0         0 return '';
108             }
109              
110 3         5 my $output = '';
111 3 50       15 $self->process($template, $self->{data}, \$output)
112             or $self->croak;
113 3         89852 return Encode::encode_utf8($output);
114             }
115              
116             sub usage {
117             return <<'...'
118             Usage:
119              
120             tt-render --path=path/to/templates/ --data=data.yaml foo.tt2
121              
122             ...
123 0     0 0 0 }
124              
125             sub croak {
126 0     0 0 0 my $self = shift;
127 0         0 require Carp;
128 0         0 my $error = $self->{tt}->error;
129 0         0 chomp $error;
130 0         0 Carp::croak($error . "\n");
131             };
132              
133             sub process {
134 3     3 1 4 my $self = shift;
135              
136 3   50     65 $self->{tt} = Template->new(
137             ENCODING => $self->{encoding},
138             INCLUDE_PATH => $self->{include_path},
139             EVAL_PERL => $self->{eval_perl},
140             START_TAG => $self->{start_tag},
141             END_TAG => $self->{end_tag},
142             PRE_CHOMP => $self->{pre_chomp},
143             POST_CHOMP => $self->{post_chomp},
144             TRIM => $self->{trim},
145             INTERPOLATE => $self->{interpolate},
146             ANYCASE => $self->{anycase},
147             DELIMITER => $self->{delimiter},
148             ABSOLUTE => $self->{absolute},
149             STRICT => $self->{strict},
150             DEFAULT => $self->{default},
151             BLOCKS => $self->{blocks},
152             AUTO_RESET => $self->{auto_reset},
153             RECURSION => $self->{recursion},
154             PRE_PROCESS => $self->{pre_process},
155             POST_PROCESS => $self->{post_process},
156             PROCESS_TEMPLATE => $self->{process_template},
157             ERROR_TEMPLATE => $self->{error_template},
158             OUTPUT_PATH => $self->{output_path},
159             DEBUG =>
160             ($self->{debug} && DEBUG_ALL ^ DEBUG_CALLER ^ DEBUG_CONTEXT),
161             CACHE_SIZE => $self->{cache_size},
162             COMPILE_EXT => $self->{compile_ext},
163             COMPILE_DIR => $self->{compile_dir},
164             );
165              
166 3         62691 return $self->{tt}->process(@_);
167             }
168              
169             sub data {
170 3     3 1 6 my $self = shift;
171 3         11 $self->{data} = $self->_file_to_hash(@_);
172 3         64548 return $self;
173             }
174              
175             sub config {
176 0     0 1 0 my $self = shift;
177 0         0 $self = {
178             %$self,
179             $self->_file_to_hash(@_)
180             };
181 0         0 return $self;
182             }
183              
184             sub _file_to_hash {
185 3     3   6 my $self = shift;
186 3         5 my $file_name = shift;
187             return
188 3 50       50 (ref($file_name) eq 'HASH')
    100          
    100          
    50          
189             ? $file_name
190             : ($file_name =~ /\.(?:yaml|yml)$/i)
191             ? $self->_load_yaml($file_name)
192             : ($file_name =~ /\.json$/i)
193             ? $self->_load_json($file_name)
194             : ($file_name =~ /\.xml$/i)
195             ? $self->_load_xml($file_name)
196             : die "Expected '$file_name' to end with .yaml, .json or .xml";
197             }
198              
199             sub _load_yaml {
200 1     1   1 my $self = shift;
201 1         6 YAML::XS::LoadFile(shift);
202             }
203              
204             sub _load_json {
205 1     1   1 my $self = shift;
206 1         11 require JSON::XS;
207 1         2 my $json = do { local $/; open my $json, '<', shift; <$json> };
  1         4  
  1         174  
  1         96  
208 1         20 JSON::XS::decode_json($json);
209             }
210              
211             sub _load_xml {
212 1     1   2 my $self = shift;
213 1         9 require XML::Simple;
214 1         6 XML::Simple::XMLin(shift);
215             }
216              
217             sub _run_command {
218 0     0     my $class = shift;
219 0           my $self = $class->new($default);
220 0           local @ARGV = @_;
221 0 0         my $template = pop or do {
222 0           print STDERR $self->usage();
223 0           return;
224             };
225             my $setter = sub {
226 0     0     my ($name, $value) = @_;
227 0           my $method = lc($name);
228 0           $method =~ s/-/_/g;
229 0 0         $value = quotemeta($value)
230             if $method =~ /_tag$/;
231 0           $self->$method($value);
232 0           };
233 0           GetOptions(
234             map {
235 0           my $option = $_;
236 0           my $option2 = $option;
237 0 0         $option .= "|$option2" if $option2 =~ s/_/-/g;
238 0 0         $option .= "|$abbreviations->{$_}"
239             if defined $abbreviations->{$_};
240 0 0 0       $option .= ((not defined $default->{$_} or $option =~/\-tag$/) ? '=s' : '');
241 0           ($option, $setter);
242             } keys %$default
243             );
244              
245 0           print STDOUT $self->render($template);
246             }
247              
248             1;