1Template::Manual::InterUnsaelrs(C3o)ntributed Perl DocumTeenmtpaltaitoen::Manual::Internals(3)
2
3
4
6 Template::Manual::Internals - Template Toolkit internals
7
9 This section of the documentation is aimed at developers wishing to
10 know more about how the Template Toolkit works on the inside in order
11 to extend or adapt it to their own needs.
12
13 If that doesn't sound like you then you probably don't need to read
14 this. There is no test afterwards.
15
17 The Template module is simply a front end module which creates and uses
18 a Template::Service and pipes the output wherever you want it to go
19 ("STDOUT" by default, or maybe a file, scalar, etc). The
20 "Apache::Template" module (available separately from CPAN) is another
21 front end. That creates a "Template::Service::Apache" object, calls on
22 it as required and sends the output back to the relevant
23 "Apache::Request" object.
24
25 These front-end modules are really only there to handle any specifics
26 of the environment in which they're being used. The "Apache::Template"
27 front end, for example, handles "Apache::Request" specifics and
28 configuration via the httpd.conf. The regular Template front-end deals
29 with "STDOUT", variable refs, etc. Otherwise it is Template::Service
30 (or subclass) which does all the work.
31
32 The Template::Service module provides a high-quality template delivery
33 service, with bells, whistles, signed up service level agreement and a
34 30-day no quibble money back guarantee. "Have a good time, all the
35 time", that's our motto.
36
37 Within the lower levels of the Template Toolkit, there are lots of
38 messy details that we generally don't want to have to worry about most
39 of the time. Things like templates not being found, or failing to
40 parse correctly, uncaught exceptions being thrown, missing plugin
41 modules or dependencies, and so on. Template::Service hides that all
42 away and makes everything look simple to the outsider. It provides
43 extra features, like "PRE_PROCESS", "PROCESS" and "POST_PROCESS", and
44 also provides the error recovery mechanism via "ERROR". You ask it to
45 process a template and it takes care of everything for you. The
46 "Template::Service::Apache" module goes a little bit further, adding
47 some extra headers to the Apache::Request, setting a few extra template
48 variables, and so on.
49
50 For the most part, the job of a service is really just one of
51 scheduling and dispatching. It receives a request in the form of a call
52 to its process() method and schedules the named template specified as
53 an argument, and possibly several other templates ("PRE_PROCESS", etc)
54 to be processed in order. It doesn't actually process the templates
55 itself, but instead makes a process() call against a Template::Context
56 object.
57
58 Template::Context is the runtime engine for the Template Toolkit - the
59 module that hangs everything together in the lower levels of the
60 Template Toolkit and that one that does most of the real work, albeit
61 by crafty delegation to various other friendly helper modules.
62
63 Given a template name (or perhaps a reference to a scalar or file
64 handle) the context process() method must load and compile, or fetch a
65 cached copy of a previously compiled template, corresponding to that
66 name. It does this by calling on a list of one or more
67 Template::Provider objects (the "LOAD_TEMPLATES" posse) who themselves
68 might get involved with a Template::Parser to help turn source
69 templates into executable Perl code (but more on that later).
70
71 Thankfully, all of this complexity is hidden away behind a simple
72 template() method. You call it passing a template name as an argument,
73 and it returns a compiled template in the form of a Template::Document
74 object, or otherwise raises an exception.
75
76 A Template::Document is a thin object wrapper around a compiled
77 template subroutine. The object implements a process() method which
78 performs a little bit of housekeeping and then calls the template
79 subroutine. The object also defines template metadata (defined in "[%
80 META ... %]" directives) and has a block() method which returns a hash
81 of any additional "[% BLOCK xxxx %]" definitions found in the template
82 source.
83
84 So the context fetches a compiled document via its own template()
85 method and then gets ready to process it. It first updates the stash
86 (the place where template variables get defined - more on that shortly)
87 to set any template variable definitions specified as the second
88 argument by reference to hash array. Then, it calls the document
89 process() method, passing a reference to itself, the context object, as
90 an argument. In doing this, it provides itself as an object against
91 which template code can make callbacks to access runtime resources and
92 Template Toolkit functionality.
93
94 What we're trying to say here is this: not only does the
95 Template::Context object receive calls from the outside, i.e. those
96 originating in user code calling the process() method on a Template
97 object, but it also receives calls from the inside, i.e. those
98 originating in template directives of the form "[% PROCESS template
99 %]".
100
101 Before we move on to that, here's a simple structure diagram showing
102 the outer layers of the Template Toolkit heading inwards, with pseudo
103 code annotations showing a typical invocation sequence.
104
105 ,--------.
106 | Caller | use Template;
107 `--------' my $tt = Template->new( ... );
108 | $tt->process($template, \%vars);
109 | Outside
110 - - - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - T T
111 | package Template; Inside
112 V
113 +----------+ sub process($template, \%vars) {
114 | Template | $out = $self->SERVICE->process($template, $vars);
115 +----------+ print $out or send it to $self->OUTPUT;
116 | }
117 |
118 | package Template::Service;
119 |
120 | sub process($template, \%vars) {
121 | try {
122 +----------+ foreach $p in @self->PRE_PROCESS
123 | Service | $self->CONTEXT->process($p, $vars);
124 +----------+
125 | $self->CONTEXT->process($template, $vars);
126 |
127 | foreach $p @self->POST_PROCESS
128 | $self->CONTEXT->process($p, $vars);
129 | }
130 | catch {
131 | $self->CONTEXT->process($self->ERROR);
132 | }
133 | }
134 |
135 V package Template::Context;
136 +----------+
137 | Context | sub process($template, \%vars) {
138 +----------+ # fetch compiled template
139 | $template = $self->template($template)
140 | # update stash
141 | $self->STASH->update($vars);
142 | # process template
143 | $template->process($self)
144 | }
145 V
146 +----------+ package Template::Document;
147 | Document |
148 +----------+ sub process($context) {
149 $output = &{ $self->BLOCK }($context);
150 }
151
153 To understand more about what's going on in these lower levels, we need
154 to look at what a compiled template looks like. In fact, a compiled
155 template is just a regular Perl sub-routine. Here's a very simple one.
156
157 sub my_compiled_template {
158 return "This is a compiled template.\n";
159 }
160
161 You're unlikely to see a compiled template this simple unless you wrote
162 it yourself but it is entirely valid. All a template subroutine is
163 obliged to do is return some output (which may be an empty of course).
164 If it can't for some reason, then it should raise an error via "die()".
165
166 sub my_todo_template {
167 die "This template not yet implemented\n";
168 }
169
170 If it wants to get fancy, it can raise an error as a
171 Template::Exception object. An exception object is really just a
172 convenient wrapper for the '"type"' and '"info"' fields.
173
174 sub my_solilique_template {
175 die (Template::Exception->new('yorrick', 'Fellow of infinite jest'));
176 }
177
178 Templates generally need to do a lot more than just generate static
179 output or raise errors. They may want to inspect variable values,
180 process another template, load a plugin, run a filter, and so on.
181 Whenever a template subroutine is called, it gets passed a reference to
182 a Template::Context object. It is through this context object that
183 template code can access the features of the Template Toolkit.
184
185 We described earlier how the Template::Service object calls on
186 Template::Context to handle a process() request from the outside. We
187 can make a similar request on a context to process a template, but from
188 within the code of another template. This is a call from the inside.
189
190 sub my_process_template {
191 my $context = shift;
192 my $output = $context->process('header', { title => 'Hello World' })
193 . "\nsome content\n"
194 . $context->process('footer');
195 }
196
197 This is then roughly equivalent to a source template something like
198 this:
199
200 [% PROCESS header
201 title = 'Hello World'
202 %]
203 some content
204 [% PROCESS footer %]
205
206 Template variables are stored in, and managed by a Template::Stash
207 object. This is a blessed hash array in which template variables are
208 defined. The object wrapper provides get() and set() method which
209 implement all the magical.variable.features of the Template Toolkit.
210
211 Each context object has its own stash, a reference to which can be
212 returned by the appropriately named stash() method. So to print the
213 value of some template variable, or for example, to represent the
214 following source template:
215
216 <title>[% title %]</title>
217
218 we might have a subroutine definition something like this:
219
220 sub {
221 my $context = shift;
222 my $stash = $context->stash();
223 return '<title>' . $stash->get('title') . '</title>';
224 }
225
226 The stash get() method hides the details of the underlying variable
227 types, automatically calling code references, checking return values,
228 and performing other such tricks. If '"title"' happens to be bound to a
229 subroutine then we can specify additional parameters as a list
230 reference passed as the second argument to get().
231
232 [% title('The Cat Sat on the Mat') %]
233
234 This translates to the stash call:
235
236 $stash->get([ 'title', ['The Cat Sat on the Mat'] ]);
237
238 Dotted compound variables can be requested by passing a single list
239 reference to the "get()" method in place of the variable name. Each
240 pair of elements in the list should correspond to the variable name and
241 reference to a list of arguments for each dot-delimited element of the
242 variable.
243
244 [% foo(1, 2).bar(3, 4).baz(5) %]
245
246 is thus equivalent to
247
248 $stash->get([ foo => [1,2], bar => [3,4], baz => [5] ]);
249
250 If there aren't any arguments for an element, you can specify an empty,
251 zero or null argument list.
252
253 [% foo.bar %]
254 $stash->get([ 'foo', 0, 'bar', 0 ]);
255
256 The set() method works in a similar way. It takes a variable name and a
257 variable value which should be assigned to it.
258
259 [% x = 10 %]
260 $stash->set('x', 10);
261
262 [% x.y = 10 %]
263 $stash->set([ 'x', 0, 'y', 0 ], 10);
264
265 So the stash gives us access to template variables and the context
266 provides the higher level functionality.
267
268 Alongside the process() method lies the include() method. Just as with
269 the "PROCESS" / "INCLUDE" directives, the key difference is in variable
270 localisation. Before processing a template, the "process()" method
271 simply updates the stash to set any new variable definitions,
272 overwriting any existing values. In contrast, the "include()" method
273 creates a copy of the existing stash, in a process known as cloning the
274 stash, and then uses that as a temporary variable store. Any previously
275 existing variables are still defined, but any changes made to
276 variables, including setting the new variable values passed aas
277 arguments will affect only the local copy of the stash (although note
278 that it's only a shallow copy, so it's not foolproof). When the
279 template has been processed, the "include()" method restores the
280 previous variable state by decloning the stash.
281
282 The context also provides an insert() method to implement the "INSERT"
283 directive, but no "wrapper()" method. This functionality can be
284 implemented by rewriting the Perl code and calling "include()".
285
286 [% WRAPPER foo -%]
287 blah blah [% x %]
288 [%- END %]
289
290 $context->include('foo', {
291 content => 'blah blah ' . $stash->get('x'),
292 });
293
294 Other than the template processing methods "process()", "include()" and
295 "insert()", the context defines methods for fetching plugin objects,
296 plugin(), and filters, filter().
297
298 # TT USE directive
299 [% USE foo = Bar(10) %]
300
301 # equivalent Perl
302 $stash->set('foo', $context->plugin('Bar', [10]));
303
304 # TT FILTER block
305 [% FILTER bar(20) %]
306 blah blah blah
307 [% END %]
308
309 # equivalent Perl
310 my $filter = $context->filter('bar', [20]);
311 &$filter('blah blah blah');
312
313 Pretty much everything else you might want to do in a template can be
314 done in Perl code. Things like "IF", "UNLESS", "FOREACH" and so on all
315 have direct counterparts in Perl.
316
317 # TT IF directive
318 [% IF msg %]
319 Message: [% msg %]
320 [% END %];
321
322 # equivalent Perl
323 if ($stash->get('msg')) {
324 $output .= 'Message: ';
325 $output .= $stash->get('msg');
326 }
327
328 The best way to get a better understanding of what's going on
329 underneath the hood is to set the $Template::Parser::DEBUG flag to a
330 true value and start processing templates. This will cause the parser
331 to print the generated Perl code for each template it compiles to
332 "STDERR". You'll probably also want to set the
333 $Template::Directive::PRETTY option to have the Perl pretty-printed for
334 human consumption.
335
336 use Template;
337 use Template::Parser;
338 use Template::Directive;
339
340 $Template::Parser::DEBUG = 1;
341 $Template::Directive::PRETTY = 1;
342
343 my $template = Template->new();
344 $template->process(\*DATA, { cat => 'dog', mat => 'log' });
345
346 __DATA__
347 The [% cat %] sat on the [% mat %]
348
349 The output sent to "STDOUT" remains as you would expect:
350
351 The dog sat on the log
352
353 The output sent to "STDERR" would look something like this:
354
355 compiled main template document block:
356 sub {
357 my $context = shift || die "template sub called without context\n";
358 my $stash = $context->stash;
359 my $output = '';
360 my $error;
361
362 eval { BLOCK: {
363 $output .= "The ";
364 $output .= $stash->get('cat');
365 $output .= " sat on the ";
366 $output .= $stash->get('mat');
367 $output .= "\n";
368 } };
369 if ($@) {
370 $error = $context->catch($@, \$output);
371 die $error unless $error->type eq 'return';
372 }
373
374 return $output;
375 }
376
378 Please feel free to hack on the Template Toolkit. If you find a bug
379 that needs fixing, if you have an idea for something that's missing, or
380 you feel inclined to tackle something on the TODO list, then by all
381 means go ahead and do it!
382
383 If you're contemplating something non-trivial then you'll probably want
384 to bring it up on the mailing list first to get an idea about the
385 current state of play, find out if anyone's already working on it, and
386 so on.
387
388 When you start to hack on the Template Toolkit, please make sure you
389 start from the latest developer release. Stable releases are uploaded
390 to CPAN and have all-numerical version numbers, e.g. 2.04, 2.05.
391 Developer releases are available from the Template Toolkit web site and
392 have a character suffix on the version, e.g. 2.04a, 2.04b, etc.
393
394 Once you've made your changes, please remember to update the test suite
395 by adding extra tests to one of the existing test scripts in the "t"
396 sub-directory, or by adding a new test script of your own. And of
397 course, run "make test" to ensure that all the tests pass with your new
398 code.
399
400 Don't forget that any files you do add will need to be added to the
401 MANIFEST. Running "make manifest" will do this for you, but you need
402 to make sure you haven't got any other temporary files lying around
403 that might also get added to it.
404
405 Documentation is often something that gets overlooked but it's just as
406 important as the code. If you're adding a new module, a plugin module,
407 for example, then it's OK to include the POD documentation in with the
408 module, but please write it all in one piece at the end of the file,
409 after the code (just look at any other "Template::*" module for an
410 example). It's a religious issue, I know, but I have a strong distaste
411 for POD documentation interspersed throughout the code. In my not-so-
412 humble opinion, it makes both the code and the documentation harder to
413 read (same kinda problem as embedding Perl in HTML).
414
415 To share your changes with the rest of the world, you'll need to
416 prepare a patch file. To do this you should have 2 directories side-
417 by-side, one which is the original, unmodified distribution directory
418 for the latest developer release, and the other is a copy of that same
419 directory which includes your changes.
420
421 The following example shows a typical hacking session. First we unpack
422 the latest developer release.
423
424 $ tar zxf Template-Toolkit-2.05c.tar.gz
425
426 At this point, it's a good idea to rename the directory to give some
427 indicate of what it contains.
428
429 $ mv Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack
430
431 Then go hack!
432
433 $ cd Template-Toolkit-2.05c-abw-xyz-hack
434
435 [ hacking ]
436
437 $ cd ..
438
439 When you're all done and ready to prepare a patch, unpack the
440 distribution archive again so that you've got the original to "diff"
441 against your new code.
442
443 $ tar zxf Template-Toolkit-2.05c.tar.gz
444
445 You should now have an original distribution directory and a modified
446 version of that same directory, side-by-side.
447
448 $ ls
449 Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack
450
451 Now run "diff" and save the output into an appropriately named patch
452 file.
453
454 $ diff -Naur Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack > patch-TT205c-abw-xyz-hack
455
456 You can then post the generated patch file to the mailing list,
457 describing what it does, why it does it, how it does it and any other
458 relevant information.
459
460 If you want to apply someone else's patch then you should start with
461 the same original distribution source on which the patch is based.
462 From within the root of the distribution, run "patch" feeding in the
463 patch file as standard input. The '"p1"' option is required to strip
464 the first element of the path name (e.g.
465 "Template-Toolkit-2.05c/README" becomes "README" which is then the
466 correct path).
467
468 $ tar zxf Template-Toolkit-2.05c.tar.gz
469 $ cd Template-Toolkit-2.05c
470 $ patch -p1 < ../patch-TT205c-abw-xyz-hack
471
472 The output generated by "patch" should be something like the following:
473
474 patching file README
475 patching file lib/Template.pm
476 patching file lib/Template/Provider.pm
477 patching file t/provider.t
478
479
480
481perl v5.16.3 2011-12-20 Template::Manual::Internals(3)