line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
8
|
|
|
8
|
|
141105
|
use strict; |
|
8
|
|
|
|
|
20
|
|
|
8
|
|
|
|
|
307
|
|
2
|
8
|
|
|
8
|
|
43
|
use warnings; |
|
8
|
|
|
|
|
15
|
|
|
8
|
|
|
|
|
324
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
package Config::TT2; |
5
|
|
|
|
|
|
|
|
6
|
8
|
|
|
8
|
|
8327
|
use Template; |
|
8
|
|
|
|
|
229967
|
|
|
8
|
|
|
|
|
246
|
|
7
|
8
|
|
|
8
|
|
5553
|
use Try::Tiny; |
|
8
|
|
|
|
|
9226
|
|
|
8
|
|
|
|
|
487
|
|
8
|
8
|
|
|
8
|
|
50
|
use Carp qw(croak); |
|
8
|
|
|
|
|
17
|
|
|
8
|
|
|
|
|
5510
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $VERSION = '0.53'; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Config::TT2 - Reading configuration files with the Template-Toolkit parser. |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 ABSTRACT |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Define configuration files in the powerful, flexible and extensible Template-Toolkit syntax. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=cut |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub new { |
23
|
31
|
|
|
31
|
1
|
34376
|
my $class = shift; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# params as HASH or HASHREF? |
26
|
31
|
100
|
100
|
|
|
255
|
my $params = defined( $_[0] ) && ref( $_[0] ) eq 'HASH' ? shift : {@_}; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# |
29
|
|
|
|
|
|
|
# Warn for unsupported Template and Template::Service params. |
30
|
|
|
|
|
|
|
# Our entry level is Template::Context, see Template::Manual::Internals |
31
|
|
|
|
|
|
|
# |
32
|
31
|
|
|
|
|
167
|
my @unsupported = qw( |
33
|
|
|
|
|
|
|
PRE_PROCESS |
34
|
|
|
|
|
|
|
PROCESS |
35
|
|
|
|
|
|
|
POST_PROCESS |
36
|
|
|
|
|
|
|
WRAPPER |
37
|
|
|
|
|
|
|
AUTO_RESET |
38
|
|
|
|
|
|
|
DEFAULT |
39
|
|
|
|
|
|
|
OUTPUT |
40
|
|
|
|
|
|
|
OUTPUT_PATH |
41
|
|
|
|
|
|
|
ERROR |
42
|
|
|
|
|
|
|
ERRORS |
43
|
|
|
|
|
|
|
); |
44
|
|
|
|
|
|
|
|
45
|
31
|
|
|
|
|
75
|
foreach my $unsupported (@unsupported) { |
46
|
265
|
100
|
|
|
|
2239
|
croak "Option '$unsupported' not supported\n" |
47
|
|
|
|
|
|
|
if exists $params->{$unsupported}; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# |
51
|
|
|
|
|
|
|
# DEFAULTS, see Template::Manual::Config |
52
|
|
|
|
|
|
|
# |
53
|
21
|
|
|
|
|
120
|
my $defaults = { |
54
|
|
|
|
|
|
|
STRICT => 1, |
55
|
|
|
|
|
|
|
ABSOLUTE => 1, |
56
|
|
|
|
|
|
|
RELATIVE => 1, |
57
|
|
|
|
|
|
|
CACHE_SIZE => 0, |
58
|
|
|
|
|
|
|
}; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# override defaults by params |
61
|
21
|
|
|
|
|
165
|
my $self = bless { _PARAMS => { %$defaults, %$params } }, $class; |
62
|
|
|
|
|
|
|
|
63
|
21
|
|
66
|
|
|
371
|
my $tt = Template->new( $self->{_PARAMS} ) || croak "$Template::ERROR\n"; |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# our entry level into TT2 is Template::Context to get the stash back |
66
|
20
|
|
|
|
|
258377
|
$self->context( $tt->service->context ); |
67
|
|
|
|
|
|
|
|
68
|
20
|
|
|
|
|
269
|
return $self; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub context { |
72
|
57
|
|
|
57
|
1
|
295
|
my ( $self, $ctx ) = @_; |
73
|
57
|
100
|
|
|
|
187
|
$self->{_CONTEXT} = $ctx if defined $ctx; |
74
|
57
|
|
|
|
|
173
|
return $self->{_CONTEXT}; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub process { |
78
|
19
|
|
|
19
|
1
|
444
|
my ( $self, $template, $vars ) = @_; |
79
|
|
|
|
|
|
|
|
80
|
19
|
|
|
|
|
48
|
my $ctx = $self->context; |
81
|
19
|
|
|
|
|
73
|
my $stash = $ctx->stash; |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# |
84
|
|
|
|
|
|
|
# processing template from Template::Context level and NOT |
85
|
|
|
|
|
|
|
# from Template::Service level to get the stash back |
86
|
|
|
|
|
|
|
# |
87
|
19
|
|
|
|
|
81
|
my ( $output, $error ); |
88
|
|
|
|
|
|
|
try { |
89
|
19
|
|
|
19
|
|
782
|
my $comp_template = $ctx->template($template); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# play Template::Service, preset template slot |
92
|
17
|
|
|
|
|
297753
|
$vars->{template} = $comp_template; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# ok, process at Template::Context level |
95
|
17
|
|
|
|
|
106
|
$output = $ctx->process( $comp_template, $vars ); |
96
|
|
|
|
|
|
|
} |
97
|
19
|
|
|
2
|
|
200
|
catch { $error = $_ }; |
|
2
|
|
|
|
|
155
|
|
98
|
19
|
100
|
|
|
|
9353
|
croak "$error" if $error; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# remove initial stash keys like _STRICT, _DEBUG, inc, ... |
101
|
17
|
|
|
|
|
75
|
$self->_purge_stash; |
102
|
|
|
|
|
|
|
|
103
|
17
|
100
|
|
|
|
107
|
return wantarray ? ( $ctx->stash, $output ) : $ctx->stash; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub _purge_stash { |
107
|
17
|
|
|
17
|
|
40
|
my $self = shift; |
108
|
|
|
|
|
|
|
|
109
|
17
|
|
|
|
|
72
|
my @purge_keys = qw( |
110
|
|
|
|
|
|
|
template |
111
|
|
|
|
|
|
|
component |
112
|
|
|
|
|
|
|
inc |
113
|
|
|
|
|
|
|
dec |
114
|
|
|
|
|
|
|
_PARENT |
115
|
|
|
|
|
|
|
_STRICT |
116
|
|
|
|
|
|
|
_DEBUG |
117
|
|
|
|
|
|
|
); |
118
|
|
|
|
|
|
|
|
119
|
17
|
|
|
|
|
66
|
my $stash = $self->context->stash; |
120
|
|
|
|
|
|
|
|
121
|
17
|
50
|
|
|
|
197
|
if ( $stash->{_DEBUG} ) { |
122
|
0
|
|
|
|
|
0
|
my $pkg = __PACKAGE__; |
123
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
0
|
warn "[${pkg}::_purge_stash] purging keys:\n"; |
125
|
0
|
|
|
|
|
0
|
warn join( ', ', @purge_keys ) . "\n"; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
17
|
|
|
|
|
51
|
foreach my $key (@purge_keys) { |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# |
131
|
|
|
|
|
|
|
# initial root VMethods inc, dec |
132
|
|
|
|
|
|
|
# |
133
|
119
|
100
|
100
|
|
|
694
|
if ( $key eq 'inc' || $key eq 'dec' ) { |
134
|
34
|
50
|
|
|
|
143
|
delete $stash->{$key} if ref $stash->{$key} eq 'CODE'; |
135
|
34
|
|
|
|
|
60
|
next; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
85
|
|
|
|
|
234
|
delete $stash->{$key}; |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head1 SYNOPSIS |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
use Config::TT2; |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
my $ctt2 = Config::TT2->new; |
147
|
|
|
|
|
|
|
my $cfg_stash = $ctt2->process($file); |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
=head1 DESCRIPTION |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
C<< Config::TT2 >> extends the C<< Template-Toolkit >> aka C<< TT2 >> in a very special way: |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
It returns the B<< VARIABLES STASH >> instead of the template text! |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
The TT2 syntax is very powerful, flexible and extensible. One of the key features of TT2 is the ability to bind template variables to any kind of Perl data: scalars, lists, hash arrays, sub-routines and objects. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
See L<< Template::Manual::Variables >> for a reference. |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
E.g. this Template-Toolkit config |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
[% # tt2 directive start-tag |
162
|
|
|
|
|
|
|
scalar = 'string' # strings in single or double quotes |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
array = [ 10 20 30 ] # commas are optional |
165
|
|
|
|
|
|
|
rev = array.reverse # powerful virtual methods |
166
|
|
|
|
|
|
|
item = array.0 # interpolate previous value |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
hash = { foo = 'bar' # hashes to any depth |
169
|
|
|
|
|
|
|
moo = array # points to above arrayref |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
%] # tt2 directive end-tag |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
is returned as a perl datastructure: |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
'scalar' => 'string' |
176
|
|
|
|
|
|
|
'array' => ARRAY(0x8ad2708) |
177
|
|
|
|
|
|
|
0 10 |
178
|
|
|
|
|
|
|
1 20 |
179
|
|
|
|
|
|
|
2 30 |
180
|
|
|
|
|
|
|
'rev' => ARRAY(0x8afe740) |
181
|
|
|
|
|
|
|
0 30 |
182
|
|
|
|
|
|
|
1 20 |
183
|
|
|
|
|
|
|
2 10 |
184
|
|
|
|
|
|
|
'item' => 10 |
185
|
|
|
|
|
|
|
'hash' => HASH(0x8afe160) |
186
|
|
|
|
|
|
|
'foo' => 'bar' |
187
|
|
|
|
|
|
|
'moo' => ARRAY(0x8ad2708) |
188
|
|
|
|
|
|
|
-> REUSED_ADDRESS |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head1 METHODS |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 new(%config) |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
The C<< new() >> constructor method instantiates a new C object. This method croaks on error. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Configuration items may be passed as a list of items or a hash array: |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
my $ctt2 = Config::TT2->new( |
199
|
|
|
|
|
|
|
ABSOLUTE => 0, |
200
|
|
|
|
|
|
|
DEBUG => 'all', |
201
|
|
|
|
|
|
|
); |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
The supported configuration options are the same as for C<< Template >>, please see the L<< Template::Manual::Config >> as a reference and the LIMITATIONS section below. |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
The preset default options which differ from the Template default options are: |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
STRICT = 1 # undefined vars or values cause exceptions |
208
|
|
|
|
|
|
|
ABSOLUTE = 1 # files with absolute filenames allowed |
209
|
|
|
|
|
|
|
RELATIVE = 1 # files with relative filenames allowed |
210
|
|
|
|
|
|
|
CACHE_SIZE = 0 # don't cache compiled config files |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head2 process($config, $variables) |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
The C<< process() >> method is called to process a config file or string. The first parameter indicates the input as one of: a filename; a reference to a text string containing the config text; or a file handle reference, from which the config can be read. |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
A reference to a hash array may be passed as the second parameter, containing definitions of input variables. |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
$stash = $ctt2->process( '.app.cfg', {foo => $ENV{APP_FOO}} ); |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
The returned datastructure is a C<< Template::Stash >> object. You may access the key and values through normal perl dereferencing: |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
$item = $stash->{hash}{moo}[0]; |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
or via the C<< Template::Stash->get >> method like: |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
$item = $stash->get('hash.moo.0'); |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
For debugging purposes you can even request the template output from the process method: |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
($stash, $output) = $ctt2->process( $config ); |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
The method croaks on error. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 LIMITATIONS |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
The Template-Toolkit processor uses the toplevel variables C<< template >> und C<< component >> for meta information during template file processing. You B<< MUST NOT >> define or redefine these toplevel variables at object creation, processing or within the config files. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
See the section L<< Template::Manual::Variables/Special Variables >>. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
The C<< process >> method purges these toplevel variables unconditionally after processing but before returning the stash. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
See also the special meaning of the C<< global >> toplevel variable. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
Successive calls to C<< process >> with the same Config::TT2 instance B<< MUST >> be avoided. The Template CONTEXT and STASH have states belonging to the processed config text. Create new instances for successive C<< process >> calls. |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
$stash1 = Config::TT2->new->process($file1); |
247
|
|
|
|
|
|
|
$stash2 = Config::TT2->new->process($file2); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
The following Template options are not supported with Config::TT2: |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
PRE_PROCESS |
252
|
|
|
|
|
|
|
PROCESS |
253
|
|
|
|
|
|
|
POST_PROCESS |
254
|
|
|
|
|
|
|
WRAPPER |
255
|
|
|
|
|
|
|
AUTO_RESET |
256
|
|
|
|
|
|
|
DEFAULT |
257
|
|
|
|
|
|
|
OUTPUT |
258
|
|
|
|
|
|
|
OUTPUT_PATH |
259
|
|
|
|
|
|
|
ERROR |
260
|
|
|
|
|
|
|
ERRORS |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head1 EXTENSIONS AND VIRTUAL METHODS |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
With the C<< context >> method you can get/set the underlying Template::Context object. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 context() |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Getter/setter method for the underlying Template::Context object. |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
With the context you can also access the stash and define new virtual methods BEFORE processing. |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
$ctt2 = Config::TT2->new; |
273
|
|
|
|
|
|
|
$ctt2->context->stash->define_vmethod( $type, $name, $code_ref ); |
274
|
|
|
|
|
|
|
$cfg_stash = $ctt2->process($cfg_file); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
See the manuals L<< Template::Stash >>, L<< Template::Context >> and L<< Template::Manual::Internals >>. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=head1 SEE ALSO |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
L<< Config::Any::TT2 >>, the corresponding L<< Config::Any >> plugin. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
L<< Template::Manual::Intro >>, L<< Template::Manual::Syntax >>, L<< Template::Manual::Config >>, L<< Template::Manual::Variables >>, L<< Template::Manual::VMethods >> |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head1 AUTHOR |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Karl Gaissmaier, C<< >> |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 BUGS |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Please report any bugs or feature requests to C, or through |
291
|
|
|
|
|
|
|
the web interface at L. I will be notified, and then you'll |
292
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
=head1 SUPPORT |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
perldoc Config::TT2 |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
You can also look for information at: |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=over 4 |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker (report bugs here) |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
L |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
L |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=item * CPAN Ratings |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
L |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
=item * Search CPAN |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
L |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=back |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Copyright 2012 Karl Gaissmaier. |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
328
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
329
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=cut |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
1; # End of Config::TT2 |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# vim: sw=4 |