Perhaps the biggest limitation of the previous example is that the presentation template isn't at all modular. In this example, we're going to split the one large template into a number of smaller ones placed in separate files. This makes the main template much simpler and easier to follow. It also allows each of the individual template components to be updated in isolation. If you want to change the display of the game averages, for example, then you just need to edit the status template and can leave everything else as it is.

We're also going to use a standard html/page template, provided as part of the Template Toolkit, to generate the required container elements to make a valid HTML page. The default location for these templates is /usr/local/tt2/templates. You will also need to define the directory in which you're going to put the hangman templates. So, to the top of the previous script, we can add the following constant definitions (tailor them to your local values, of course):

use constant TEMPLATES => '/home/stas/templates/hangman2';
use constant SHARED    => '/usr/local/tt2/templates';

Then, when we create the Template object, we specify these directories as a list reference for the INCLUDE_PATH option:

# create a Template object
my $tt = Template->new({
    INCLUDE_PATH => [ TEMPLATES, SHARED ],
});

The rest of the script remains the same, with exception of the template specified in the __DATA__section. This can now be written as:

__DATA__
Content-type: text/html

[% WRAPPER html/page
     html.head.title  = title
     html.body.onload = 'if (document.gf) document.gf.guess.focus( )'
%]

[% PROCESS header %]

[% IF status =  = 'won' or status =  = 'lost';
      PROCESS restart;
   ELSE;
      PROCESS guess;
   END
%]

[% PROCESS footer %]

[% END %]

We've moved the header, the footer, and the two different variants of the form out into separate templates. The entire page is enclosed within a WRAPPER block, which generates the required <html>, <head>, and <body> tags to wrap around the page using the standard html/page template.

The external header and footer templates are shown in Examples D-6 and D-7. According to the value of TEMPLATESset above, these should be located in /home/stas/templates/hangman.

Example D-6. hangman2/templates/header

<h1>[% title %]</h1>

[% # how many guesses left to go?
   tries_left = tries - state.left
%]

[%# display the appropriate image -%]  
<img src="[% icons %]/h[% tries_left %].gif"
     align="left" alt="[[% tries_left %] tries left]" />

[% # display the game averages
   PROCESS status 
%]

Example D-7. hangman2/templates/footer

<br clear="all">
<hr />

<a href="[% url %]">Home</a>

<p>
  <cite style="fontsize: 10pt">graphics courtesy Andy Wardley</cite>
</p>