DESCRIPTION

The Template module is a simple front-end to the Template Toolkit. It implements a generic template processing object which loads and uses other Template Toolkit modules as required to process template documents.

use Template;
my $tproc = Template->new();

Constants defined in Template::Constants can be imported by specifying import tag sets as parameters to the use Template statement.

use Template qw( :status );

The object may be configured by passing a hash reference to the new() constructor.

my $tproc = Template->new({
    INTERPOLATE => 1,
    PRE_CHOMP   => 1,
});

Templates are rendered by calling the process() method on the Template object. The first parameter specifies the template input and may be a filename, a reference to a text string (SCALAR) containing template text or a reference to a GLOB or IO::Handle (or sub-class) from which the template should be read. The process returns 1 if the template was successfully rendered or 0 if an error occurred. In the latter case, the relevant error message can be retrieved by calling the error() method.

$tproc->process($myfile)
    || die $tproc->error(), "\n";

The second optional parameter may be a hash reference which defines variables for use in the template. The entries in this hash may be simple values, references to hashes, lists, sub-routines or objects (described in detail below).

my $data = {
    'name' => 'John Doe'
    'id'   => 'jdoe',
};

$tproc->process($myfile, $data) 
    || die $tproc->error(), "\n";

The PRE_PROCESS and POST_PROCESS options may be used to specify the name(s) of template file(s) that should be processed immediately before and after each template, respectively. This can be used to add page headers and footers, for example.

TEMPLATE SYNTAX AND DIRECTIVES

DIRECTIVE TAGS

The default syntax for embedding directives in template documents is to enclose them within the character sequences '[%' and '%]'.

  [% INCLUDE header %]

  <h1>Hello World!</h1>
  <a href="[% page.next %]"><img src="[% icon.next %].gif"></a>

  [% INCLUDE footer %]

For backwards compatibility with Text::MetaText, the default TAG_STYLE also allows the '%%' token to be used as both the start and end of tags.

%% INCLUDE header %%    # for backwards compatibility

You can change the tag characters using the START_TAG, END_TAG and TAG_STYLE options, described below. You can also use the TAGS directive to change the tags on a per-file basis. The new tag definitions last only for the current template file. The TAGS directive should contain two whitespace delimited character sequences to represent the START and END tags.

[% TAGS <!-- --> %]
<!-- INCLUDE header title = 'Hello World!' -->

Directives may be embedded anywhere in a line of text and can be split across several lines. Whitespace is generally ignored within the directive, except where used to separate parameters.

  [% INCLUDE header		   
     title  = 'Hello World' 
     bgcol  = '#ffffff' 
  %]

  [%INCLUDE menu align='right'%]

  Name: [% name %]  ([%id%])

Directives that start with a '#' are treated as comments and ignored. No output is generated. This is useful for commenting template documents or temporarily disabling certain directives.

[% # This is a comment and will be ignored %]

CLEANING UP WHITESPACE

Anything outside a directive tag is considered plain text and is generally passed through unaltered (but see INTERPOLATE below). This includes all the whitespace and newlines characters surrounding directive tags. When tags are processed, they may generate no output but leave a 'gap' in the output document.

Example:

Foo
[% a = 10 %]
Bar

Output:

Foo

Bar

The PRE_CHOMP and POST_CHOMP options help to reduce this extraneous whitespace. If a directive appears at the start of a line, or on a line with nothing but whitespace in front of it, then a PRE_CHOMP will delete any whitespace and the preceding newline character. This effectively moves the directive up onto the previous line. When a directive appears at the end of a line, or on a line with nothing but whitespace following it, then a POST_CHOMP will delete any whitespace and the following newline. This effectively moves the next line up onto the current line.

	Foo <----------.
		       |
   ,---(PRE-CHOMP)----'
   |
   `-- [% a = 10 %] --.
		       |
   ,---(POST-CHOMP)---'
   |
   `-> Bar

The '-' or '+' processing flags may be added immediately inside the start/end tags to enable or disable pre/post chomping options on a per-directive basis.

[%  a = b  %]   # default PRE_CHOMP and POST_CHOMP
[%- a = b  %]   # do PRE_CHOMP  (remove start of line if blank)
[%  a = b -%]   # do POST_CHOMP (remove rest of line if blank)
[%+ a = b  %]   # don't PRE_CHOMP  (leave start of line intact)
[%  a = b +%]   # don't POST_CHOMP (leave rest of line intact)

See the PRE_CHOMP and POST_CHOMP configuration options, described below.

VARIABLES

Directives generally comprise a keyword such as INCLUDE, FOREACH, IF, etc., possibly followed by one or more expressions, parameters, etc.

The GET and SET directives are provided to retrieve (print) and update variable values, respectively. For the sake of brevity, the GET and SET keywords can be omitted and a lone variable will be implicitly treated as a GET directive while an assignment, or sequence of assignments will be implicitly treated as a SET directive.

 # explicit
 [% GET foo %]
 [% SET bar=baz %]
 [% SET 
    name  = 'Fred'
    email = 'fred@happy.com'
 %]

 # implicit (preferred)
 [% foo %]
 [% bar=baz %]
 [% name  = 'Fred'
    email = 'fred@happy.com'
 %]

The DEFAULT directive is similar to SET but only updates variables that are currently undefined or have no "true" value (in the Perl sense).

[% DEFAULT
   name = 'John Doe'
   id   = 'jdoe'
%]

The INTERPOLATE option allows you to embed variables directly into text without requiring the '[%' and '%]' tags. Instead, the variable name should be prefixed by a '$'. You can use curly braces to explicitly delimit the variable name when required:

# INTERPOLATE => 1
<a href="$page.next"><img src="${icon.next}.gif"></a>

With INTERPOLATE set on, any other '$' characters in your document should be 'escaped' by prefixing them with a '\':

Cost: \$100

BLOCK DIRECTIVES

The FOREACH, WHILE, BLOCK, FILTER and CATCH directives mark the start of a block which may contain text or other directives (including other nested blocks) up to the next (balanced) END directive. The IF, UNLESS, ELSIF and ELSE directives also define blocks and may be grouped together in the usual manner.

  Metavars:
  [% FOREACH item = [ 'foo' 'bar' 'baz' ] %]
     * Item: [% item %]
  [% END %]

  [% BLOCK footer %]
     Copyright 1999 [% me %]
     [% INCLUDE company/logo %]
  [% END %]

  [% CATCH file %]
     <!-- File error: [% e.info %] -->
     [% IF debugging %]
	  [% INCLUDE debugtxt  msg = "file: $e.info" %]
     [% END %]
  [% END %]

  [% IF foo %]
     do this...
  [% ELSIF bar %]
     do that...
  [% ELSE %]
     do nothing...
  [% END %]

DIRECTIVE SYNTAX AND STRUCTURE

Multiple directives may be included within a single tag by separating them with semi-colons.

  [% IF debugging; 
	 INCLUDE debugtxt  msg = "file: $e.info;
     END 
  %]

Note that the TAGS directive must always be specified in a tag by itself.

The IF, UNLESS, FOREACH, WHILE and FILTER block directives may be specified immediately after another directive (except other block directives) in a convenient 'side-effect' notation.

[% INCLUDE userinfo FOREACH user = userlist %]
[% INCLUDE debugtxt msg="file: $e.info" IF debugging %] 
[% "Danger Will Robinson" IF atrisk %]

The directive keyword may be specified in any case but you might find that it helps to adopt the convention of always using UPPER CASE to make them visually distinctive from variables.

[% FOREACH item = biglist %]   # Good.  
[% foreach item = biglist %]   # OK, but not recommended

Variable names may contain any alphanumeric characters or underscores. They may be lower, upper or mixed case although the usual convention is to use lower case. The case is significant however, and 'foo', 'Foo' and 'FOO' are all different variables.

The fact that a keyword may be expressed in any case, precludes you from using any variable that has the same name as a reserved word, irrespective of its case. Reserved words are:

GET, SET, DEFAULT, INCLUDE, PROCESS, IMPORT, FILTER, USE
FOR, FOREACH, IF, UNLESS, ELSE, ELSIF, AND, OR, NOT 
BLOCK, END, THROW, CATCH, ERROR, RETURN, STOP, PERL

e.g. [% include = 10 %] # error - 'INCLUDE' a reserved word

The CASE option forces all directive keywords to be expressed in UPPER CASE. Any word not in UPPER CASE will be treated as a variable. This then allows you to use lower, or mixed case variable names that match reserved words. The CASE option does not change the case sensitivity for variable names, only reserved words. Variable names are always case sensitive. The 'and', 'or' and 'not' operators are the only exceptions to this rule. They can always be expressed in lower, or indeed any case, irrespective of the CASE option, and as such, preclude the use of a variables by any of those names.

  # CASE => 1
  [% include = 10 %]     # OK - 'include' is a variable, 'INCLUDE' 
			   # is the reserved word.
  [% INCLUDE foobar      
	 IF foo and bar    # OK - 'and' can always be lower case
  %]

VARIABLE NAMESPACES (HASHES)

The period character, '.', is used to denote separate "namespaces" for variables. A namespace is simply a variable that contains a reference to a hash array of more variables.

  my $data = {
	'home' => 'http://www.myserver.com/homepage.html',
	'user' => {
	    'name' => 'John Doe',
	    'id'   => 'jdoe',
	},
	'page' => {
	    'this' => 'mypage.html',
	    'next' => 'nextpage.html',
	    'prev' => 'prevpage.html',
	},
  };

  $tproc->process($myfile, $data) 
	|| die $tproc->error(), "\n";

Example:

<a href="[% home %]">Home</a>
<a href="[% page.prev %]">Previous Page</a>
<a href="[% page.next %]">Next Page</a>

Output:

<a href="http://www.myserver.com/homepage.html"</a>
<a href="prevpage.html">Previous Page</a>
<a href="nextpage.html">Next Page</a>

Any key in a hash which starts with a '_' or '.' character will be considered 'private' and cannot be evaluated or updated from within a template.

When you assign to a variable that contains multiple namespace elements (i.e. it has one or more '.' characters in the name), any hashes required to represent intermediate namespaces will be created automatically. In other words, you don't have to explicitly state that a variable ('product' in the next example) will represent a namespace (i.e. reference a hash), you can just use it as such and it will be created automatically.

 [% product.id    = 'XYZ-2000' 
    product.desc  = 'Bogon Generator'
    product.price = 666 
 %]

 # INTERPOLATE => 0
 The [% product.id %] [% product.desc %] 
 costs $[% product.price %].00

Output:

The XYZ-2000 Bogon Generator 
costs $666.00

If you want to create a new variable namespace (i.e. a hash) en masse, then you can use Perl's familiar '{' ... '}' construct to create a hash and assign it to a variable.

  [% product = {
	 id    = 'XYZ-2000' 
	 desc  = 'Bogon Generator'
	 price = 666 
     }
  %]
 
  # INTERPOLATE => 1
  The $product.id $product.desc 
  costs \$${product.price}.00

Output:

The XYZ-2000 Bogon Generator 
costs $666.00

Note that commas are optional between key/value pairs and the '=>' token may be used in place of '=' to make things look more familiar to Perl hackers. You can even prefix variables with '$' if you really want to but it's not necessary.

  [% product = {
	 id    => 'XYZ-2000',
	 desc  => 'Bogon Generator',
	 price => 666,
	 foo   => $bar,    # OK to use '$', but not necessary
	$baz   => $qux,    # this is also OK if you _really_ like $'s
     }
  %]

You can copy all the members of a hash into the top level variable namespace with the IMPORT directive.

  [% user = {
	 name = 'John Doe'
	 id   = 'jdoe'
     }
  %]
 
  [% IMPORT user %] 
  Name: [% name %]   ID: [% id %]

You can automatically IMPORT a hash when INCLUDE'ing another template file or block by assigning it to the upper case IMPORT variable, passed as a parameter.

  [% BLOCK one %]
     [% user.name %] [% user.email %]
  [% END %]

  [% BLOCK two %]
     [% name %] [% email %]
  [% END %]

  [% user  = { name = 'me',  email = 'me@here.com'   }
     other = { name = 'you', email = 'you@there.com' }
  %]

  [% INCLUDE one %]
  [% INCLUDE one user=other %]
  [% INCLUDE two IMPORT=user %]
  [% INCLUDE two IMPORT=other %]

VARIABLE VALUES

Variables may be assigned the values of other variables, unquoted numbers (digits), literal text ('single quotes') or quoted text ("double quotes"). In the latter case, any variable references within the text will be interpolated when the string is evaluated. Variables should be prefixed by '$', using curly braces to explicitly scope variable name where necessary.

[% foo  = 'Foo'  %]               # literal value 'Foo'
[% bar  =  foo   %]               # value of variable 'foo'
[% cost = '$100' %]               # literal value '$100'
[% item = "$foo: ${price}.00" %]  # value "bar: $100.00"

Multiple variables may be assigned in the same directive and are evaluated in the order specified. Thus, the above could have been written:

[% foo  = 'Foo'
   bar  = foo
   cost = '$100'
   item = "$foo: ${price}.00"
%]

VARIABLE LISTS

A list (actually a reference to an anonymous Perl list) can be created and assigned to a variable by enclosing one or more values in square brackets, just like in Perl. The values in the list may be any of those described above. Commas between elements are optional.

[% userlist = [ 'tom' 'dick' 'harry' ] %]

[% foo    = 'Foo'
   mylist = [ foo, 'Bar', "$foo Baz" ]
%]

The FOREACH directive will iterate through a list created as above, or perhaps provided as a pre-defined variable passed to the process() method.

  my $data = {
	'name' => 'John Doe'
	'id'   => 'jdoe',
	'items' => [ 'one', 'two', 'three' ],
  };

  $tproc->process($myfile, $data) 
	|| die $tproc->error(), "\n";

Example:

  Things:
  [% foo = 'Foo' %]
  [% FOREACH thing = [ foo 'Bar' "$foo Baz" ] %]
     * [% thing %]
  [% END %]

  Items:
  [% FOREACH i = items %]
     * [% i %]
  [% END %]

  Stuff:
  [% stuff = [ foo "$foo Bar" ] %]
  [% FOREACH s = stuff %]
     * [% s %]
  [% END %]

Output:

  Things:
    * Foo
    * Bar
    * Foo Baz

  Items:
    * one
    * two
    * three

  Stuff:
    * Foo
    * Foo Bar

When the FOREACH directive is used without specifying a target variable, any iterated values which are hash references will be automatically imported.

  # assume 'userlist' is a list of user hash refs
  [% FOREACH user = userlist %]
     [% user.name %]
  [% END %]

  # same as...
  [% FOREACH userlist %]
     [% name %]
  [% END %]

The [% BREAK %] directive can be used to prematurely exit a FOREACH loop.

VARIABLES BOUND TO USER CODE

Template variables may also contain references to Perl sub-routines (CODE). When the variable is evaluated, the code is called and the return value used in the variable's place. These "bound" variables can be used just like any other:

  my $data = {
	'magic' => \&do_magic,
  };

  $template->process('myfile', $data)
	|| die $template->error();

  sub do_magic {
	# ...whatever...
	return 'Abracadabra!';
  }

myfile:

He chanted the magic spell, "[% magic %]", and 
disappeared in a puff of smoke.

Output:

He chanted the magic spell, "Abracadabra!", and
disappeared in a puff of smoke

Any additional parameters specified in parenthesis will also be passed to the code:

    $data = {
	'foo'   => 'Mr. Foo',
	'bar'   => 'Mr. Bar',
	'qux'   => 'Qux',
	'join'  => sub { my $joint = shift; join($joint, @); },
    }

    $template->process('myfile', $data)
	|| die $template->error();

myfile:

[% join(' + ', foo, bar, 'Mr. Baz', "Mr. $qux") %]

Output:

Mr. Foo + Mr. Bar + Mr. Baz + Mr Qux

Parenthesised parameters may be added to any element of a variable, not just those that are bound to code or object methods. At present, parameters will be ignored if the variable isn't "callable" but are supported for future extensions. Think of them as "hints" to that variable, rather than just arguments passed to a function.

[% r = 'Romeo' %]
[% r(100, 99, s, t, v) %]     # still just prints "Romeo"

User code should return a value for the 'variable' to which it is bound. On error, undef can be returned which will trigger an "undef" exception to be automatically raised (see below)

sub do_magic {
    # blah blah blah
    return undef if $something_went_wrong;
    # more stuff..
    return $some_value;
}

An alternative approach which gives more flexibility is for the code to return a second value indicating the status. A status of 0 (STATUS_OK) means everything went OK, regardless of whatever value was returned, defined or not. In this case an undefined value would simply be converted to an empty string ''. In other words, no output or error would be generated.

  use Template qw( :status );
  my $DEBUG = 0;

  sub debug {
	return (undef, STATUS_OK) unless $DEBUG;
	# blah blah blah
	return $some_debug_text;
  }

The status code can also be STATUS_STOP (immediate stop) or STATUS_RETURN (stop the current template only and return to the caller or point of INCLUDE). The final option is for the status to be an exception object. This is an instance of the Template::Exception class which can be created by calling the new() construcot. The first parameter defines the 'type' of error which may have a corresponding CATCH handler defined. The second parameter should be a string containing the details of the error.

The CATCH option and CATCH block directive allow you to define custom handling, or template blocks to be processed when different kinds of exception occur, including any user-defined types such as in this example:

    use Template qw( :status );
    use Template::Exception;
  
    my $tproc = Template->new();
    $tproc->process('example', { sql => \&silly_query_language })
      || die $tproc->error(), "\n";
  
    sub silly_query_language {
  	# some code...
  
  	# stop!
  	return (undef, STATUS_STOP) if $some_fatal_error;
  
  	# some more code...
  
  	# raise a 'database' exception that might be caught and handled
  	return (undef, 
	        Template::Exception->new('database', $DBI::errstr))
  	    if $dbi_error_occurred;
  
  	# even more code still..
  
  	# OK, everything's just fine.  Return data
  	return $some_data;
    }

Example:

  [% # define a CATCH block for 'database' errors that 
     # prints the error, adds the page footer and STOPs  
  %]
  [% CATCH database %]
     <!-- Database error handler -->
     <hr>
     <h1>Database Error</h1>
     An unrecoverable database error has occurred:
     <ul>
	 [% e.info %]
     </ul>
     [% INCLUDE footer %]
     [% STOP %]
  [% END %]

  [% # we're prepared for the worst... %]
  [% sql('EXPLODE my_brain INTO a_thousand_pieces') %] 

VARIABLES BOUND TO OBJECTS

A variable may contain an object reference whose methods will be called when expressed in the 'object.method' notation. The object reference will implicitly be passed to the method as the first parameter. Any other parameters specified in parenthesis after the method name will also be passed.

  package MyObj;

  sub new {
	my $class  = shift;
	bless { }, $class;
  }

  sub bar {
    my ($self, @params) = @_;
    # do something...
    return $some_value; 
  }

  package main;

  my $tproc = Template->new();
  my $obj   = MyObj->new();
  $tproc->process('example', { 'foo' => $obj, 'baz' => 'BAZ' } )
    || die $tproc->error(), "\n";

Example:

[% foo.bar(baz) %]	# calls $obj->bar('BAZ')

Methods whose names start with an underscore (e.g. '_mymethod') will not be called. Parameter passing and return value expectations are as per code references, above.

VARIABLE EVALUATION

A 'dotted' variable may contain any number of separate elements. Each element may evaluate to one of the above variable types and the processor will then correctly use this value to evaluate the rest of the variable.

For example, consider the following variable reference:

[% myorg.user.abw.name %]

This might equate to the following fundamental steps:

'myorg'  is an object reference
'user'   is a method called on the above object returning another
         object which acts as an interface to a database
'abw'    is a method called on the above object, caught by AUTOLOAD
         triggering the retrieval of a record from the database.  
         This is returned as a hash
'name'   is fetched from this hash, representing the value of the 
         'name' field in the record.

You don't need to worry about any of the above steps because they all happen automatically. When writing a template, a variable is just a variable, irrespective of how its value is stored, retrieved or calculated.

Intermediate variables may be used and will behave entirely as expected.

[% userdb = myorg.user %]
[% user   = userdb.abw %]
Name: [% user.name %]  EMail: [% user.email %]

An element of a dotted variable can itself be an interpolated value. The variable should be enclosed within the '${' .., '}' characters. In the following example, we use a 'uid' variable interpolated into a longer variable such as the above to return multiple user records from the database.

[% userdb = myorg.user %]
[% FOREACH uid = [ 'abw' 'sam' 'hans' ] %]
   [% user = userdb.${uid} %]
   Name: [% user.name %]  EMail: [% user.email %]
%]

This could be also have been interpolated into the full variable reference:

[% uid  = 'abw'
   name = myorg.user.${uid}.name
%]

You can also use single and double quoted strings inside an interpolated element:

# contrived example
[% letterw = 'w' 
   name = myorg.user.${"ab$letterw"}.name
%]

Any namespace element in a variable may contain parenthesised parameters. If the item contains a code reference or represents an object method then the parameters will be passed to that sub-routine/method when called. Parameters are otherwise ignored, but may be used for future extensibility.

A different implementation of the above example might look like this:

[% myorg.user('abw').name %]

Here, the fictional 'user' method of the 'myorg' object takes a parameter to indicate the required record. Thus, it can directly return a hash reference representing the record which can then be examined for the 'name' member. The method could be written to check for the existence of a parameter and return a general access facility, such as the object mentioned in the previous example, if one is not provided.

    package myorg;
  
    sub user {
  	my ($self, $uid) = @_;
  	return $uid ? $self->get_record($uid) : $self
    }

    sub AUTOLOAD {
	my ($self, @params) = @_;
        my $name = $AUTOLOAD;
        $name =~ s/.*:://;
        return if $name eq 'DESTROY';
        $self->get_record($name);
    }

A sub-routine or method might also return a reference to a list containing other objects or data. The FOREACH directive is used to iterate through such lists.

[% FOREACH user = myorg.userlist %]
   Name: [% user.name %]  EMail: [% user.email %]
[% END %]

For more powerful list iteration, a Template::Iterator object can be defined and/or returned for use in a FOREACH directive. The following pseudo-code example illustrates the principal. Here, the 'userlist' method first determines a list of valid user ID's and then creates an iterator to step through them. On each iteration, the ACTION for the iterator is called, which in this case is a closure to retrieve each record from the database.

  package myorg;

  sub user {
	my ($self, $uid) = @_;
	return $self->query("SELECT * FROM user WHERE (uid='$uid')");
  }

  sub userlist {
	my $self = shift;
	my $user_id_list = $self->query("SELECT id FROM user");
	return Template::Iterator->new($user_id_list, {
	      ORDER  => 'sorted',
	      ACTION => sub { $self->user(shift) },
	});
  }

This process is entirely hidden from the template author. The use of iterators is automatic and nothing needs to change in the template:

[% FOREACH user = myorg.userlist %]
   Name: [% user.name %]  EMail: [% user.email %]
[% END %]

Underlying code, algorithms and heuristics may be as simple or as complex as required to perform the task in hand. However, the specific details of the implementation are hidden away in the "back-end", providing only a simple, clear and consistent interface for use in template documents.

CONDITIONAL BLOCKS

The IF, ELSIF and UNLESS directives can be used to process or ignore a block based on some run-time condition. Multiple conditions may be joined with ELSIF and/or ELSE blocks.

The following conditional and boolean operators may be used:

== != < <= > >= ! && || and or not

Conditions may be arbitrarily complex and are evaluated left-to-right with conditional operators having a higher precedence over boolean ones. Parenthesis may be used to explicitly determine evaluation order.

Examples:

# simple example
[% IF age < 10 %]
   Hello [% name %], does your mother know you're 
   using her AOL account?
[% ELSE %]
   Welcome [% name %].
[% END %]

# ridiculously contrived complex example
[% IF (name == 'admin' || uid <= 0) && (mode == 'debug' || debug) %]
   I'm confused.
[% ELSIF more > less %]
   That's more or less correct.
[% END %]

The WHILE directive can be used to repeatedly process a template block while an expression (as per the examples above) evaluates "true".

[% WHILE total < 100 %]
   ....
   [% total = calculate_new_total %]
[% END %]

An assignment can be enclosed in parenthesis to evaluate the assigned value.

[% WHILE (user = get_next_user_record) %]
   [% user.name %]
[% END %]

The [% BREAK %] directive can be used to prematurely exit a WHILE loop.

INCLUDING TEMPLATE FILES AND BLOCKS

The INCLUDE directive is used to process and include the output of another template file or block.

[% INCLUDE header %]

The first parameter to the INCLUDE directive is assumed to be the name of a file or defined block (see BLOCK, below). For convenience, it does not need to be quoted as long as the name contains only alphanumeric characters, underscores, dots or forward slashes. Names containing any other characters should be quoted.

[% INCLUDE misc/menu.atml               %]
[% INCLUDE 'dos98/Program Files/stupid' %]

To evaluate a variable to specify a file/block name, explicitly prefix it with a '$' or use double-quoted string interpolation.

[% language = 'en'
   header   = 'test/html/header.html' 
%]

[% INCLUDE $header %]
[% INCLUDE "$language/$header" %]

The processor will look for files relative to the directories specified in the INCLUDE_PATH. Each file is parsed when first loaded and cached internally in a "compiled" form. The contents of the template, including any directives embedded within it, will then be processed and the output included into the current document. Subsequent INCLUDE directives requesting the same file can then use the cached version to greatly reduce processing time.

You should always use the '/'character as a path separator as shown in the above examples, regardless of your local operating system convention. Perl will automatically convert this to the local equivalent for non-Unix file systems. The '/' character is therefore portable across all platforms.

The included template will "inherit" all variables currently defined in the including template.

[% title = 'Hello World'
   bgcol = '#ffffff' 
%]
[% INCLUDE header %]

header:

<html>
<head><title>[% title %]</title></head>
<body bgcolor="[% bgcol %]">

Output:

<html>
<head><title>Hello World!</title></head>
<body bgcolor="#ffffff">

The DEFAULT directive can be useful for supplying default values in commonly used template files such as this:

header:

[% DEFAULT
   title = 'The "Hello World!" Web Site'
   bgcol = '#ffffff'
-%]
<html>
<head><title>[% title %]</title></head>
<body bgcolor="[% bgcol %]">

(Note how the DEFAULT directive specifies an explicit POST_CHOMP by placing a '-' immediately before the '%]' end-of-tag characters. This tells the processor to remove the whitespace and newline that immediately follow the DEFAULT directive. One place where additional whitespace can cause problems in an HTML document is before the initial <html> tag, so we're sure to strip it out, just to be safe)

Further parameters can be provided to define local variable values for the template.

[% INCLUDE header
   title = 'Cat in the Hat'
   bgcol = '#aabbcc'
%]

Output:

<html>
<head><title>Cat in the Hat</title></head>
<body bgcolor="#aabbcc">

These variables, along with any others that might be created or used within the included template remain local to it. Changes made to them don't affect the variables in the including template, even though they may have inherited values from them.

[% name = 'foo' %] 
[% INCLUDE change_name %]
Name is still '[% name %]'

change_name:

Name is [% name %]
Changing '[% name %]' to [% name ='bar'; name %]

Output:

Name is 'foo'
Changing 'foo' to 'bar'
Name is still 'foo'

The PROCESS directive is similar to INCLUDE in all respects except that it does not perform this localisation of variables. Changes made to variables in the sub-template, and indeed any variable definitions specified in the directive, will update those variables in the including template.

[% name = 'foo'
   age  = 100
%] 
[% PROCESS change_name  age = 101 %]
Name is now '[% name %]' and age is [% age %] 

Output:

Name is 'foo'
Changing 'foo' to 'bar'
Name is now 'bar' and age is 101

This is generally useful for processing separate files that define various configuration values.

[% PROCESS myconfig %]
<img src="$images/mylogo.gif">

myconfig:

[% server   = 'www.myserver.com'
   homepage = "http://$server/"
   images   = '/images'
%]

Output:

<img src="/images/mylogo.gif">

In addition to separate files, template blocks can be defined and processed with the INCLUDE directive. These are defined with the BLOCK directive and are parsed, compiled and cached as for files.

  [% BLOCK tabrow %]
  <tr><td>[% name %]<td><td>[% email %]</td></tr>
  [% END %]

  <table>
  [% INCLUDE tabrow  name='Fred'  email='fred@nowhere.com' %]
  [% INCLUDE tabrow  name='Alan'  email='alan@nowhere.com' %]
  </table>

A BLOCK definition may be used before it is defined, as long as the definition resides in he same file.

[% INCLUDE tmpblk %]

[% BLOCK tmpblk %] This is OK [% END %]

PLUGIN OBJECTS AND LIBRARIES

The USE directive can be used to load and initialise "plugin" extension modules. These are regular Perl modules that may, or may not, be derived from the Template::Plugin base class.

[% USE myplugin %]

The plugin name is case-sensitive and will be appended to the PLUGIN_BASE value (default: 'Template::Plugin') to construct a full module name. Any periods, '.', in the name will be converted to '::'.

[% USE MyPlugin   %]     #  => Template::Plugin::MyPlugin
[% USE CGI.Params %]     #  => Template::Plugin::CGI::Params

Any additional parameters supplied in parenthesis after the plugin name will be also be passed to the new() constructor. A reference to the template Context object is always passed as the first parameter.

[% USE MyPlugin('foo', 123) %]
   ==> Template::Plugin::MyPlugin->new($context, 'foo', 123);

The plugin may represent any data type; a simple variable, hash, list or code reference, but in the general case it will be an object reference. Methods can be called on the object (or the relevant members of the specific data type) in the usual way:

[% USE MyPlugin %]
[% MyPlugin.does_this %]
[% MyPlugin.does_that %]

An alternative name may be provided for the plugin by which it can be referenced:

[% USE magic = MyPlugin %]
[% magic.supernova('Big Bang') %]

You can use this approach to create multiple plugin objects with different configurations. This example shows how the 'format' plugin is used to create sub-routines bound to variables for formatting text as per printf().

[% USE bold = format('<b>%s</b>') %]
[% USE ital = format('<i>%s</i>') %]

[% bold('This is bold')   %]
[% ital('This is italic') %]

Output:

<b>This is bold</b>
<i>This is italic</i>

The CGI plugin simply creates and returns an instance of Lincoln Stein's CGI.pm module.

[% USE CGI %]
[% name = CGI.param('username') %]

POST-PROCESSING FILTERS

The FILTER directive can be used to post-process the output of a block. The Template::Plugin::Filter module defines the 'html' and 'format' filters. The 'html' filter converts the characters '<', '>' and '&' to '&lt;', '&gt;' and '&amp', respectively, protecting them from being interpreted as representing HTML tags or entities. The 'format' filter takes a format string as a parameter (as per printf()) and formats each line of text accordingly.

  [% FILTER html %]
  Binary "<=>" returns -1, 0, or 1 depending on...
  [% END %]

  [% FILTER format('<!-- %-40s -->') %]
  This is a block of text filtered 
  through the above format.
  [% END %]

output:

  Binary "&lt;=&gt;" returns -1, 0, or 1 depending on...

  <!-- This is a block of text filtered        -->
  <!-- through the above format.               -->

Additional filters may be provided via the FILTERS configuration option.

A filter that is created without any specific parameters will be cached and re-used whenever that same filter is required. Specifying parameters to a filter will always cause a new filter instance to be created.

  [% FILTER myfilter %]
     # calls 'myfilter' factory code
     Blah Blah Blah
  [% END %]
     
  [% FILTER myfilter %]
     # re-uses cached filter created above
     Cabbages
  [% END %]

  [% FILTER myfilter('foo') %]
     # calls 'myfilter' factory code, passing 'foo'
     Rhubarb
  [% END %]

Filters that are created with parameters will not be cached unless an alias is provided for them. The filter instance can then be re-used by specifying the alias.

  [% FILTER non_atomic = censor('nuclear') %]
     # creates and runs the filter, aliasing it to non_atomic
     ...contentus maximus...
  [% END %]

  [% FILTER non_atomic %]
     # re-uses cached non_atomic filter created above
     ...ditto contentus...
  [% END %]

The FILTER facility is relatively new and still slightly immature. While it is fully functional (for the definition of 'fully' in that it works as claimed above), it is still lacking in some areas. It isn't possible, for example, to dynamically load user-defined filters from a plugin module other than Template::Plugin::Filter.pm. This will certainly be improved at some point in the future.

It should also be noted that 'html' and 'format' hardly represent a comprehensive list of the generic filters that might be widely useful. Any thoughts on this matter, ideas or code for filters, problems encountered, suggestions, solutions, etc., are welcome on the templates mailing list.

ERROR HANDLING AND FLOW CONTROL

There are two kinds of error that may occur within the Template Toolkit. The first (which we try to avoid) are 'Perl errors' caused by incorrect usage, or heaven forbid, bugs in the Template Toolkit. See the BUGS section or the TODO file for more detail on those. Thankfully, these are comparatively rare and most problems are simply due to calling a method incorrectly or passing the wrong parameters.

The Template Toolkit doesn't go out of it's way to check every parameter you pass it. On the whole, it is fairly tolerant and will leave it up to Perl's far superior error checking to report anything seriously untoward that occurs.

The other kind of errors that concerns us more are those relating to the template processing "runtime". These are the (un)expected things that happen when a template is being processed that we might be interested in finding out about. They don't mean that the Template Toolkit has failed to do what was asked of it, but rather that what was asked of it didn't make sense, or didn't work as it should. These kind of errors might include a variable being used that isn't defined ('undef'), a file that couldn't be found, or properly parsed for an INCLUDE directive ('file'), a database query that failed in some user code, a calculation that contains an illegal value, an invalid value for some verified data, and so on (any error types can be user-defined).

These kinds of errors are raised as 'exceptions'. An exception has a 'type' which is a single word describing the kind of error, and an 'info' field containing any additional information.

These exceptions may be caught (i.e. "handled") by an entry defined in the hash array passed as the CATCH parameter to the Template constructor. The keys in the hash represent the error types and the values should contain a status code (e.g. STATUS_OK, STATUS_STOP) or a code reference which will be called when exceptions of that type are thrown. Such code references are passed three parameters; a reference to the template "Context" object, the error type and the error info. Having performed any processing, it should then return a status code or an exception object to be propagated back to the user. Returning a value of 0 (STATUS_OK) indicates that the exception has been successfully handled and processing should continue as before.

  my $tproc = Template->new({	
	CATCH => {
	  'undef' => STATUS_OK,
	  'file'  => sub {
			my ($context, $type, $info) = @_;
			$context->output("<!-- $type: ($info) -->");
			return STATUS_OK;
		     },
	},
  });

A template block may also be defined that will be processed when certain exception types are raised. The CATCH directive starts the block definition and should contain a single word denoting the error type. The variable 'e' will be defined in a catch block representing the error. The 'type' and 'info' members represent the appropriate values.

[% CATCH file %]
  <!-- file error: [% e.info %] -->
[% END %]

A CATCH block defined without an error type will become a default handler. This will be processed when an exception is raised that has no specific handler of its own defined.

[% CATCH %]
  An error ([% e.type %]) occurred: 
    [% e.info %]
[% END %]

A default handler can be installed via the CATCH option by defining the error type as 'default'.

my $tproc = Template->new({	
    CATCH => {
        'default' => STATUS_OK,
    },
});

Any user-defined exception types can be created, returned, thrown and caught at will. User code may return an exception as the status code to indicate an error. This exception type can then be caught in the usual way.

  $tproc->process('myexample', { 'go_mad' => \&go_mad })
    || die $tproc->error();

  sub go_mad {
	return (undef, Template::Exception->new('mad', 
                                              'Big Fat Error'));
  }

Example:

[% CATCH mad %]
Gone mad: [% e.info %]
[% END %]

Going insane...
[% go_mad %]

Output:

Going insane...
Gone mad: Big Fat Error

A CATCH block will be installed at the point in the template at which it is defined and remains available thereafter for the lifetime of the template processor or until redefined. This is probably a bug and may soon be 'fixed' so that handlers defined in templates only persist until the parent process() method ends.

An exception that is not caught, or one that is caught by a handler that then propagates the exception onward, will cause the Template process() method to stop and return a false status (failed). A string representing the exception that occurred (in the format "$type: $info") can be returned by calling the error() method.

$tproc->process('myexample')
    || die "PROCESSING ERROR: ", $tproc->error(), "\n";

You can 'throw' an exception using the THROW directive, specifying the error type (unquoted) and value to represent the information.

[% THROW up 'Feeling Sick' %]

Output:

PROCESSING ERROR: up: Feeling Sick

The STOP directive can be used to indicate that the processor should stop gracefully without processing any more of the template document. This is known as a 'planned stop' and the Template process() method will return a true value. This indicates 'the template was processed successfully according to the directives within it' which hopefully, it was. If you need to find out if the template ended 'naturally' or via a STOP (or RETURN, as discussed below) directive, you can call the Template error() method which will return the numerical value returned from the last directive, represented by the constants STATUS_OK, STATUS_STOP, STATUS_RETURN, etc. If the previous process() did not return a true value then the error() method returns a string representing the exception that occurred.

The STOP directive can be used in conjunction with CATCH blocks to safely trap and report any fatal errors and then end the template process gracefully.

[% CATCH fatal_db_error %]
   <p>
   <b>A fatal database error has occurred</b>
   <br>
   Error: [% e.info %]
   <br>
   We apologise for the inconvenience.  The cleaning lady 
   has removed the server power to plug in her vacuum cleaner.
   Please try again later.
   </p>
   [% ERROR "[$e.type] $e.info" %]
   [% INCLUDE footer %]
   [% STOP %]
[% END %]

The ERROR directive as used in the above example, sends the specified value to the current output stream for the template processor. By default, this is STDERR.

The RETURN directive is similar to STOP except that it terminates the current template file only. If the file in which the RETURN directive exists has been INCLUDE'd by another, then processing will continue at the point immediately after the INCLUDE directive.

  Before
  [% INCLUDE half_wit %]
  After

  [% BLOCK half_wit %]
  This is just half...
  [% RETURN %]
  ...a complete block
  [% END %]

Output:

Before
This is just half...
After

The STOP, RETURN, THROW and ERROR directives can all be used in conjunction with other 'side-effect' directives. e.g.

  [% THROW up 'Contents of stomach' IF drunk %]
  [% STOP IF brain_exploded %]
  [% RETURN IF no_input %]
  [% ERROR 'Stupid, stupid, user' IF easy2guess(passwd) %]
  [% THROW badpasswd "$user.id has a dumb password ($user.passwd)"
	 FOREACH user = naughty_user_list
  %]