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 The source code repository for the Template Toolkit is hosted at
389 Github.
390
391 https://github.com/abw/Template2
392
393 Clone the repository, make your changes, commit them, then send a pull
394 request.
395
396 Once you've made your changes, please remember to update the test suite
397 by adding extra tests to one of the existing test scripts in the "t"
398 sub-directory, or by adding a new test script of your own. And of
399 course, run "make test" to ensure that all the tests pass with your new
400 code.
401
402 Don't forget that any files you do add will need to be added to the
403 MANIFEST. Running "make manifest" will do this for you, but you need
404 to make sure you haven't got any other temporary files lying around
405 that might also get added to it.
406
407 Documentation is often something that gets overlooked but it's just as
408 important as the code. If you're adding a new module, a plugin module,
409 for example, then it's OK to include the POD documentation in with the
410 module, but please write it all in one piece at the end of the file,
411 after the code (just look at any other "Template::*" module for an
412 example). It's a religious issue, I know, but I have a strong distaste
413 for POD documentation interspersed throughout the code. In my not-so-
414 humble opinion, it makes both the code and the documentation harder to
415 read (same kinda problem as embedding Perl in HTML).
416
417 Then add a line to the Changes file giving a very brief description of
418 what you've done. There's no need to go into detail here (save that
419 for the commit message, comments in code or docuemtation where
420 appropriate).
421
422 Please also make sure you add your name to the
423 lib/Template/Manual/Credits.pod file (if it isn't already there).
424
425 Then commit your changes and send a pull request.
426
427
428
429perl v5.36.0 2022-07-22 Template::Manual::Internals(3)