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