1Template::Manual::InterUnsaelrs(C3o)ntributed Perl DocumTeenmtpaltaitoen::Manual::Internals(3)
2
3
4

NAME

6       Template::Manual::Internals - Template Toolkit internals
7

Introduction

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

Outside Looking In

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

Inside Looking Out

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

Hacking on the Template Toolkit

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)
Impressum