File: Internals.html

package info (click to toggle)
libtemplate-perl 2.24-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 8,660 kB
  • sloc: perl: 14,518; makefile: 15; sh: 5
file content (646 lines) | stat: -rwxr-xr-x 37,219 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN">
<html>
  <head>
    <title>Template::Manual::Internals</title>
    <link rel="stylesheet" type="text/css" href="../css/blue.css" title="Clear Blue">
    <link rel="alternate stylesheet" type="text/css" href="../css/orange.css" title="Clear Orange">
    <link rel="alternate stylesheet" type="text/css" href="../css/green.css" title="Clear Green">
    <link rel="alternate stylesheet" type="text/css" href="../css/purple.css" title="Clear Purple">
    <link rel="alternate stylesheet" type="text/css" href="../css/grey.css" title="Clear Grey">
    <!--[if IE 6]>
    <link rel="stylesheet" type="text/css" href="../css/ie6.css" />
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/css/print.css" media="print">
    <script type="text/javascript" src="../js/tt2.js"></script>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <meta name="author" content="Andy Wardley">
  </head>
  <body id="body"> 
    <div id="layout">
        <div id="header">
          <a href="../index.html" id="logo" alt="" title="Click for the Home Page"><span class="alt">TT2 Home Page</span></a>
          <ul id="trail">
            <li><a href="../manual/index.html">Manual</a></li>
            <li class="last"><a href="../manual/Internals.html">Internals</a></li>
          </ul>
          <div class="controls">
            <a href="#" class="menu show" onclick="widescreen_off(); return false" title="Show Menu">
              <span class="about">Click to view the menu.  It's very nice.</span>
            </a>
            <a href="#" class="menu hide" onclick="widescreen_on();  return false" title="Hide Menu">
              <span class="about">Click to hide the menu and go all widescreen!</span>
            </a>
          
          <div class="pager">
            <a href="../manual/Plugins.html" title="Template::Manual::Plugins" class="go back">Back<span class="about"><h4>Template::Manual::Plugins</h4>Standard plugins</span></a>
            <a href="../manual/index.html" title="Template::Manual" class="go up">Up<span class="about"><h4>Template::Manual</h4>Template Toolkit User Manual</span></a>
            <a href="../manual/Views.html" title="Template::Manual::Views" class="go next">Next<span class="about"><h4>Template::Manual::Views</h4>Template Toolkit views (experimental)</span></a>
          </div>
          </div>
          <h1 class="headline">Template::Manual::Internals</h1>
          <h2 class="subhead">Template Toolkit internals</h1>
        
        </div>
        <div id="page">
          <div id="sidebar">
            <a href="../index.html" id="logo"></a>
            <div id="menu">
              <ul class="menu">
                <li class="l0 first"><a href="../manual/index.html" class="warm">Manual</a></li>
                <li class="l1"><a href="../manual/Intro.html">Intro</a></li>
                <li class="l1"><a href="../manual/Syntax.html">Syntax</a></li>
                <li class="l1"><a href="../manual/Directives.html">Directives</a></li>
                <li class="l1"><a href="../manual/Variables.html">Variables</a></li>
                <li class="l1"><a href="../manual/VMethods.html">VMethods</a></li>
                <li class="l1"><a href="../manual/Config.html">Config</a></li>
                <li class="l1"><a href="../manual/Filters.html">Filters</a></li>
                <li class="l1"><a href="../manual/Plugins.html">Plugins</a></li>
                <li class="l1"><a href="../manual/Internals.html" class="warm">Internals</a></li>
                <li class="l1"><a href="../manual/Views.html">Views</a></li>
                <li class="l1"><a href="../manual/Credits.html">Credits</a></li>
                <li class="l0"><a href="../modules/index.html">Modules</a></li>
                <li class="l0"><a href="../tools/index.html">Tools</a></li>
                <li class="l0 last"><a href="../tutorial/index.html">Tutorial</a></li>
              </ul>
              <div class="foot"></div>
            </div>
          </div>
          <div id="content">
          <div class="section">
            <div class="head">
              <h1 id="contents" onclick="switch_section(this)" title="Click title to show/hide section content.">Contents</h1>
              <a href="#body" class="top" title="Back up to the top of the page" >Top</a>
            </div>
            <div class="body">
              <ul class="toc">
                  <li class=""><a href="#Outside_Looking_In">Outside Looking In</a></li>
                  <li class=""><a href="#Inside_Looking_Out">Inside Looking Out</a></li>
                  <li class=""><a href="#Hacking_on_the_Template_Toolkit">Hacking on the Template Toolkit</a></li>
              
              </ul>
            </div>
          </div>
          
                <div class="pod">
            <div class="section">
              <div class="head">
                <h1 id="Outside_Looking_In" onclick="switch_section(this)" title="Click title to show/hide section content.">Outside Looking In</h1>
                <a href="#body" class="top" title="Back up to the top of the page" >Top</a>
              </div>
              <div class="body">
                <p>
                      The <a href="../modules/Template.html">Template</a> module is simply
                      a front end module which creates and uses a <a href="../modules/Template/Service.html">Template::Service</a> and pipes the
                      output wherever you want it to go (<code>STDOUT</code> by default, or
                      maybe a file, scalar, etc). The <code>Apache::Template</code> module
                      (available separately from CPAN) is another front end. That creates a
                      <code>Template::Service::Apache</code> object, calls on it as required
                      and sends the output back to the relevant <code>Apache::Request</code>
                      object.
                    </p>
                    <p>
                      These front-end modules are really only there to handle any specifics of
                      the environment in which they're being used. The
                      <code>Apache::Template</code> front end, for example, handles
                      <code>Apache::Request</code> specifics and configuration via the
                      <i>httpd.conf</i>. The regular <a href="../modules/Template.html">Template</a> front-end deals with <code>STDOUT</code>, variable
                      refs, etc. Otherwise it is <a href="../modules/Template/Service.html">Template::Service</a> (or subclass) which does all the work.
                    </p>
                    <p>
                      The <a href="../modules/Template/Service.html">Template::Service</a> module provides a high-quality template
                      delivery service, with bells, whistles, signed up service level agreement
                      and a 30-day no quibble money back guarantee. "Have a good time, all the
                      time", that's our motto.
                    </p>
                    <p>
                      Within the lower levels of the Template Toolkit, there are lots of messy
                      details that we generally don't want to have to worry about most of the
                      time. Things like templates not being found, or failing to parse
                      correctly, uncaught exceptions being thrown, missing plugin modules or
                      dependencies, and so on. <a href="../modules/Template/Service.html">Template::Service</a> hides that all away and makes everything look
                      simple to the outsider. It provides extra features, like
                      <code>PRE_PROCESS</code>, <code>PROCESS</code> and
                      <code>POST_PROCESS</code>, and also provides the error recovery mechanism
                      via <code>ERROR</code>. You ask it to process a template and it takes
                      care of everything for you. The <code>Template::Service::Apache</code>
                      module goes a little bit further, adding some extra headers to the <a
                      href="http://search.cpan.org/search?query=Apache::Request&mode=all">Apache::Request</a>, setting a
                      few extra template variables, and so on.
                    </p>
                    <p>
                      For the most part, the job of a service is really just one of scheduling
                      and dispatching. It receives a request in the form of a call to its <a
                      href="#method_process">Template::Service#process()</a> method and
                      schedules the named template specified as an argument, and possibly
                      several other templates (<code>PRE_PROCESS</code>, etc) to be processed
                      in order. It doesn't actually process the templates itself, but instead
                      makes a <a href="#method_process">Template::Context#process()</a> call
                      against a <a href="../modules/Template/Context.html">Template::Context</a> object.
                    </p>
                    <p>
                      <a href="../modules/Template/Context.html">Template::Context</a> is
                      the runtime engine for the Template Toolkit - the module that hangs
                      everything together in the lower levels of the Template Toolkit and that
                      one that does most of the real work, albeit by crafty delegation to
                      various other friendly helper modules.
                    </p>
                    <p>
                      Given a template name (or perhaps a reference to a scalar or file handle)
                      the context process() method must load and compile, or fetch a cached
                      copy of a previously compiled template, corresponding to that name. It
                      does this by calling on a list of one or more <a href="../modules/Template/Provider.html">Template::Provider</a> objects (the
                      <code>LOAD_TEMPLATES</code> posse) who themselves might get involved with
                      a <a href="../modules/Template/Parser.html">Template::Parser</a> to
                      help turn source templates into executable Perl code (but more on that
                      later).
                    </p>
                    <p>
                      Thankfully, all of this complexity is hidden away behind a simple <a
                      href="#method_template">Template::Context#template()</a> method. You call
                      it passing a template name as an argument, and it returns a compiled
                      template in the form of a <a href="../modules/Template/Document.html">Template::Document</a> object, or otherwise raises an exception.
                    </p>
                    <p>
                      A <a href="../modules/Template/Document.html">Template::Document</a> is a thin object wrapper around a compiled
                      template subroutine. The object implements a <a
                      href="#method_process">Template::Document#process()</a> method which
                      performs a little bit of housekeeping and then calls the template
                      subroutine. The object also defines template metadata (defined in
                      <code>[% META ... %]</code> directives) and has a <a
                      href="#method_block">Template::Document#block()</a> method which returns
                      a hash of any additional <code>[% BLOCK xxxx %]</code> definitions found
                      in the template source.
                    </p>
                    <p>
                      So the context fetches a compiled document via its own <a
                      href="#method_template">Template::Context#template()</a> method and then
                      gets ready to process it. It first updates the stash (the place where
                      template variables get defined - more on that shortly) to set any
                      template variable definitions specified as the second argument by
                      reference to hash array. Then, it calls the document <a
                      href="#method_process">Template::Document#process()</a> method, passing a
                      reference to itself, the context object, as an argument. In doing this,
                      it provides itself as an object against which template code can make
                      callbacks to access runtime resources and Template Toolkit functionality.
                    </p>
                    <p>
                      What we're trying to say here is this: not only does the <a href="../modules/Template/Context.html">Template::Context</a> object receive
                      calls from the <i>outside</i>, i.e. those originating in user code
                      calling the process() method on a Template object, but it also receives
                      calls from the <i>inside</i>, i.e. those originating in template
                      directives of the form <code>[% PROCESS template %]</code>.
                    </p>
                    <p>
                      Before we move on to that, here's a simple structure diagram showing the
                      outer layers of the Template Toolkit heading inwards, with pseudo code
                      annotations showing a typical invocation sequence.
                    </p>
                    <pre> ,--------.
 | Caller |     use Template;
 `--------'     my $tt = Template-&gt;new( ... );
      |         $tt-&gt;process($template, \%vars);
      |                                                     Outside
- - - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - T T 
      |         package Template;                            Inside
      V
+----------+    sub process($template, \%vars) {
| Template |        $out = $self-&gt;SERVICE-&gt;process($template, $vars);
+----------+        print $out or send it to $self-&gt;OUTPUT;
      |         }
      |
      |         package Template::Service;
      |
      |         sub process($template, \%vars) {
      |             try {
+----------+            foreach $p in @self-&gt;PRE_PROCESS
| Service  |                $self-&gt;CONTEXT-&gt;process($p, $vars);
+----------+
      |                 $self-&gt;CONTEXT-&gt;process($template, $vars);
      |
      |                 foreach $p @self-&gt;POST_PROCESS
      |                     $self-&gt;CONTEXT-&gt;process($p, $vars);
      |             }
      |             catch {
      |                 $self-&gt;CONTEXT-&gt;process($self-&gt;ERROR);
      |             }
      |         }
      |
      V         package Template::Context;
+----------+    
| Context  |    sub process($template, \%vars) {
+----------+        # fetch compiled template
      |             $template = $self-&gt;template($template)
      |             # update stash
      |             $self-&gt;STASH-&gt;update($vars);
      |             # process template
      |             $template-&gt;process($self)
      |         }
      V     
+----------+    package Template::Document;
| Document |    
+----------+    sub process($context) {
                    $output = &amp;{ $self-&gt;BLOCK }($context);
                }</pre>
              </div>
            </div>
            <div class="section">
              <div class="head">
                <h1 id="Inside_Looking_Out" onclick="switch_section(this)" title="Click title to show/hide section content.">Inside Looking Out</h1>
                <a href="#body" class="top" title="Back up to the top of the page" >Top</a>
              </div>
              <div class="body">
                <p>
                      To understand more about what's going on in these lower levels, we need
                      to look at what a compiled template looks like. In fact, a compiled
                      template is just a regular Perl sub-routine. Here's a very simple one.
                    </p>
                    <pre>sub my_compiled_template {
    return "This is a compiled template.\n";
}</pre>
                    <p>
                      You're unlikely to see a compiled template this simple unless you wrote
                      it yourself but it is entirely valid. All a template subroutine is
                      obliged to do is return some output (which may be an empty of course). If
                      it can't for some reason, then it should raise an error via
                      <code>die()</code>.
                    </p>
                    <pre>sub my_todo_template {
    die "This template not yet implemented\n";
}</pre>
                    <p>
                      If it wants to get fancy, it can raise an error as a <a href="../modules/Template/Exception.html">Template::Exception</a> object. An
                      exception object is really just a convenient wrapper for the
                      '<code>type</code>' and '<code>info</code>' fields.
                    </p>
                    <pre>sub my_solilique_template {
    die (Template::Exception-&gt;new('yorrick', 'Fellow of infinite jest'));
}</pre>
                    <p>
                      Templates generally need to do a lot more than just generate static
                      output or raise errors. They may want to inspect variable values, process
                      another template, load a plugin, run a filter, and so on. Whenever a
                      template subroutine is called, it gets passed a reference to a <a
                      href="../modules/Template/Context.html">Template::Context</a>
                      object. It is through this context object that template code can access
                      the features of the Template Toolkit.
                    </p>
                    <p>
                      We described earlier how the <a href="../modules/Template/Service.html">Template::Service</a> object calls on <a href="../modules/Template/Context.html">Template::Context</a> to handle a <a
                      href="#method_process">Template::Context#process()</a> request from the
                      <i>outside</i>. We can make a similar request on a context to process a
                      template, but from within the code of another template. This is a call
                      from the <i>inside</i>.
                    </p>
                    <pre>sub my_process_template {
    my $context = shift;
    my $output = $context-&gt;process('header', { title =&gt; 'Hello World' })
               . "\nsome content\n"
               . $context-&gt;process('footer');
}</pre>
                    <p>
                      This is then roughly equivalent to a source template something like this:
                    </p>
                    <pre>[% PROCESS header
    title = 'Hello World'
%]
some content
[% PROCESS footer %]</pre>
                    <p>
                      Template variables are stored in, and managed by a <a href="../modules/Template/Stash.html">Template::Stash</a> object. This is a
                      blessed hash array in which template variables are defined. The object
                      wrapper provides <a href="#method_get">Template::Stash#get()</a> and <a
                      href="#method_set">Template::Stash#set()</a> method which implement all
                      the <i>magical.variable.features</i> of the Template Toolkit.
                    </p>
                    <p>
                      Each context object has its own stash, a reference to which can be
                      returned by the appropriately named <a
                      href="#method_stash">Template::Context#stash()</a> method. So to print
                      the value of some template variable, or for example, to represent the
                      following source template:
                    </p>
                    <pre>&lt;title&gt;[% title %]&lt;/title&gt;</pre>
                    <p>
                      we might have a subroutine definition something like this:
                    </p>
                    <pre>sub {
    my $context = shift;
    my $stash = $context-&gt;stash();
    return '&lt;title&gt;' . $stash-&gt;get('title') . '&lt;/title&gt;';
}</pre>
                    <p>
                      The stash <a href="#method_get">Template::Stash#get()</a> method hides
                      the details of the underlying variable types, automatically calling code
                      references, checking return values, and performing other such tricks. If
                      '<code>title</code>' happens to be bound to a subroutine then we can
                      specify additional parameters as a list reference passed as the second
                      argument to get().
                    </p>
                    <pre>[% title('The Cat Sat on the Mat') %]</pre>
                    <p>
                      This translates to the stash call:
                    </p>
                    <pre>$stash-&gt;get([ 'title', ['The Cat Sat on the Mat'] ]);</pre>
                    <p>
                      Dotted compound variables can be requested by passing a single list
                      reference to the <code>get()</code> method in place of the variable name.
                      Each pair of elements in the list should correspond to the variable name
                      and reference to a list of arguments for each dot-delimited element of
                      the variable.
                    </p>
                    <pre>[% foo(1, 2).bar(3, 4).baz(5) %]</pre>
                    <p>
                      is thus equivalent to
                    </p>
                    <pre>$stash-&gt;get([ foo =&gt; [1,2], bar =&gt; [3,4], baz =&gt; [5] ]);</pre>
                    <p>
                      If there aren't any arguments for an element, you can specify an empty,
                      zero or null argument list.
                    </p>
                    <pre>[% foo.bar %]
$stash-&gt;get([ 'foo', 0, 'bar', 0 ]);</pre>
                    <p>
                      The <a href="#method_set">Template::Stash#set()</a> method works in a
                      similar way. It takes a variable name and a variable value which should
                      be assigned to it.
                    </p>
                    <pre>[% x = 10 %]         
$stash-&gt;set('x', 10);

[% x.y = 10 %]
$stash-&gt;set([ 'x', 0, 'y', 0 ], 10);</pre>
                    <p>
                      So the stash gives us access to template variables and the context
                      provides the higher level functionality.
                    </p>
                    <p>
                      Alongside the <a href="#method_process">Template::Context#process()</a>
                      method lies the <a href="#method_include">Template::Context#include()</a>
                      method. Just as with the <code>PROCESS</code> / <code>INCLUDE</code>
                      directives, the key difference is in variable localisation. Before
                      processing a template, the <code>process()</code> method simply updates
                      the stash to set any new variable definitions, overwriting any existing
                      values. In contrast, the <code>include()</code> method creates a copy of
                      the existing stash, in a process known as <i>cloning</i> the stash, and
                      then uses that as a temporary variable store. Any previously existing
                      variables are still defined, but any changes made to variables, including
                      setting the new variable values passed aas arguments will affect only the
                      local copy of the stash (although note that it's only a shallow copy, so
                      it's not foolproof). When the template has been processed, the
                      <code>include()</code> method restores the previous variable state by
                      <i>decloning</i> the stash.
                    </p>
                    <p>
                      The context also provides an <a
                      href="#method_insert">Template::Context#insert()</a> method to implement
                      the <code>INSERT</code> directive, but no <code>wrapper()</code> method.
                      This functionality can be implemented by rewriting the Perl code and
                      calling <code>include()</code>.
                    </p>
                    <pre>[% WRAPPER foo -%]
   blah blah [% x %]
[%- END %]

$context-&gt;include('foo', {
    content =&gt; 'blah blah ' . $stash-&gt;get('x'),
});</pre>
                    <p>
                      Other than the template processing methods <code>process()</code>,
                      <code>include()</code> and <code>insert()</code>, the context defines
                      methods for fetching plugin objects, <a
                      href="#method_plugin">Template::Context#plugin()</a>, and filters, <a
                      href="#method_filter">Template::Context#filter()</a>.
                    </p>
                    <pre># TT USE directive
[% USE foo = Bar(10) %]

# equivalent Perl
$stash-&gt;set('foo', $context-&gt;plugin('Bar', [10]));</pre>
                    <pre># TT FILTER block
[% FILTER bar(20) %]
   blah blah blah
[% END %]

# equivalent Perl
my $filter = $context-&gt;filter('bar', [20]);
&amp;$filter('blah blah blah');</pre>
                    <p>
                      Pretty much everything else you might want to do in a template can be
                      done in Perl code. Things like <code>IF</code>, <code>UNLESS</code>,
                      <code>FOREACH</code> and so on all have direct counterparts in Perl.
                    </p>
                    <pre># TT IF directive
[% IF msg %]
   Message: [% msg %]
[% END %];</pre>
                    <pre># equivalent Perl
if ($stash-&gt;get('msg')) {
    $output .=  'Message: ';
    $output .= $stash-&gt;get('msg');
}</pre>
                    <p>
                      The best way to get a better understanding of what's going on underneath
                      the hood is to set the <code>$Template::Parser::DEBUG</code> flag to a
                      true value and start processing templates. This will cause the parser to
                      print the generated Perl code for each template it compiles to
                      <code>STDERR</code>. You'll probably also want to set the
                      <code>$Template::Directive::PRETTY</code> option to have the Perl
                      pretty-printed for human consumption.
                    </p>
                    <pre>use Template;
use Template::Parser;
use Template::Directive;

$Template::Parser::DEBUG = 1;
$Template::Directive::PRETTY = 1;

my $template = Template-&gt;new();
$template-&gt;process(\*DATA, { cat =&gt; 'dog', mat =&gt; 'log' });

__DATA__
The [% cat %] sat on the [% mat %]</pre>
                    <p>
                      The output sent to <code>STDOUT</code> remains as you would expect:
                    </p>
                    <pre>The dog sat on the log</pre>
                    <p>
                      The output sent to <code>STDERR</code> would look something like this:
                    </p>
                    <pre>compiled main template document block:
sub {
    my $context = shift || die "template sub called without context\n";
    my $stash   = $context-&gt;stash;
    my $output  = '';
    my $error;

    eval { BLOCK: {
        $output .=  "The ";
        $output .=  $stash-&gt;get('cat');
        $output .=  " sat on the ";
        $output .=  $stash-&gt;get('mat');
        $output .=  "\n";
    } };
    if ($@) {
        $error = $context-&gt;catch($@, \$output);
        die $error unless $error-&gt;type eq 'return';
    }

    return $output;
}</pre>
              </div>
            </div>
            <div class="section">
              <div class="head">
                <h1 id="Hacking_on_the_Template_Toolkit" onclick="switch_section(this)" title="Click title to show/hide section content.">Hacking on the Template Toolkit</h1>
                <a href="#body" class="top" title="Back up to the top of the page" >Top</a>
              </div>
              <div class="body">
                <p>
                      Please feel free to hack on the Template Toolkit. If you find a bug that
                      needs fixing, if you have an idea for something that's missing, or you
                      feel inclined to tackle something on the TODO list, then by all means go
                      ahead and do it!
                    </p>
                    <p>
                      If you're contemplating something non-trivial then you'll probably want
                      to bring it up on the mailing list first to get an idea about the current
                      state of play, find out if anyone's already working on it, and so on.
                    </p>
                    <p>
                      When you start to hack on the Template Toolkit, please make sure you
                      start from the latest developer release. Stable releases are uploaded to
                      CPAN and have all-numerical version numbers, e.g. 2.04, 2.05. Developer
                      releases are available from the Template Toolkit web site and have a
                      character suffix on the version, e.g. 2.04a, 2.04b, etc.
                    </p>
                    <p>
                      Once you've made your changes, please remember to update the test suite
                      by adding extra tests to one of the existing test scripts in the
                      <code>t</code> sub-directory, or by adding a new test script of your own.
                      And of course, run <code>make test</code> to ensure that all the tests
                      pass with your new code.
                    </p>
                    <p>
                      Don't forget that any files you do add will need to be added to the
                      MANIFEST. Running <code>make manifest</code> will do this for you, but
                      you need to make sure you haven't got any other temporary files lying
                      around that might also get added to it.
                    </p>
                    <p>
                      Documentation is often something that gets overlooked but it's just as
                      important as the code. If you're adding a new module, a plugin module,
                      for example, then it's OK to include the POD documentation in with the
                      module, but <i>please</i> write it all in one piece at the end of the
                      file, <i>after</i> the code (just look at any other
                      <code>Template::*</code> module for an example). It's a religious issue,
                      I know, but I have a strong distaste for POD documentation interspersed
                      throughout the code. In my not-so-humble opinion, it makes both the code
                      and the documentation harder to read (same kinda problem as embedding
                      Perl in HTML).
                    </p>
                    <p>
                      To share your changes with the rest of the world, you'll need to prepare
                      a patch file. To do this you should have 2 directories side-by-side, one
                      which is the original, unmodified distribution directory for the latest
                      developer release, and the other is a copy of that same directory which
                      includes your changes.
                    </p>
                    <p>
                      The following example shows a typical hacking session. First we unpack
                      the latest developer release.
                    </p>
                    <pre>$ tar zxf Template-Toolkit-2.05c.tar.gz</pre>
                    <p>
                      At this point, it's a good idea to rename the directory to give some
                      indicate of what it contains.
                    </p>
                    <pre>$ mv Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack</pre>
                    <p>
                      Then go hack!
                    </p>
                    <pre>$ cd Template-Toolkit-2.05c-abw-xyz-hack</pre>
                    <pre>[ hacking ]</pre>
                    <pre>$ cd ..</pre>
                    <p>
                      When you're all done and ready to prepare a patch, unpack the
                      distribution archive again so that you've got the original to
                      <code>diff</code> against your new code.
                    </p>
                    <pre>$ tar zxf Template-Toolkit-2.05c.tar.gz</pre>
                    <p>
                      You should now have an original distribution directory and a modified
                      version of that same directory, side-by-side.
                    </p>
                    <pre>$ ls
Template-Toolkit-2.05c  Template-Toolkit-2.05c-abw-xyz-hack</pre>
                    <p>
                      Now run <code>diff</code> and save the output into an appropriately named
                      patch file.
                    </p>
                    <pre>$ diff -Naur Template-Toolkit-2.05c Template-Toolkit-2.05c-abw-xyz-hack &gt; patch-TT205c-abw-xyz-hack</pre>
                    <p>
                      You can then post the generated patch file to the mailing list,
                      describing what it does, why it does it, how it does it and any other
                      relevant information.
                    </p>
                    <p>
                      If you want to apply someone else's patch then you should start with the
                      same original distribution source on which the patch is based. From
                      within the root of the distribution, run <code>patch</code> feeding in
                      the patch file as standard input. The '<code>p1</code>' option is
                      required to strip the first element of the path name (e.g.
                      <code>Template-Toolkit-2.05c/README</code> becomes <code>README</code>
                      which is then the correct path).
                    </p>
                    <pre>$ tar zxf Template-Toolkit-2.05c.tar.gz
$ cd Template-Toolkit-2.05c
$ patch -p1 &lt; ../patch-TT205c-abw-xyz-hack</pre>
                    <p>
                      The output generated by <code>patch</code> should be something like the
                      following:
                    </p>
                    <pre>patching file README
patching file lib/Template.pm
patching file lib/Template/Provider.pm
patching file t/provider.t</pre>
              </div>
            </div>
            
            </div></div>
          <br class="clear" />
          <div class="pageinfo">
            /manual/Internals.html last modified 10:57:40 31-May-2007
          </div>
        </div>
        
        <div id="footer">
          <a href="http://opensource.org/" class="osi"></a>
          <div class="controls">
          <div class="pager">
            <a href="../manual/Plugins.html" title="Template::Manual::Plugins" class="go back">Back<span class="about"><h4>Template::Manual::Plugins</h4></span></a>
            <a href="../manual/index.html" title="Template::Manual" class="go up">Up<span class="about"><h4>Template::Manual</h4></span></a>
            <a href="../manual/Views.html" title="Template::Manual::Views" class="go next">Next<span class="about"><h4>Template::Manual::Views</h4></span></a>
          </div>
          </div>
          <div class="copyright">
            Copyright &copy; 1996-2007 <a href="http://wardley.org/">Andy Wardley</a>.  All Rights Reserved.
          </div>
          <div class="licence">
            The <a href="http://template-toolkit.org/">Template Toolkit</a> is <a href="http://opensource.org/">Open Source</a> software.
            You can redistribute and/or modify it under the terms of the <a href="http://www.opensource.org/licenses/gpl-license.php">GNU Public Licence</a>
            or the <a href="http://www.opensource.org/licenses/artistic-license.php">Perl Artistic Licence</a>.
          </div>
        </div>
        <div id="palette">
          <ul>
            <li class="first"><a href="#" class="blue" onclick="set_style('Clear Blue')"></a></li>
            <li><a href="#" class="orange" onclick="set_style('Clear Orange')"></a></li>
            <li><a href="#" class="green" onclick="set_style('Clear Green')"></a></li>
            <li><a href="#" class="purple" onclick="set_style('Clear Purple')"></a></li>
            <li><a href="#" class="grey" onclick="set_style('Clear Grey')"></a></li>
          </ul>
        </div>
    </div>  </body>
</html>