variable to retrieve information about the currently caught exception.
For example, the \f(CW\*(C`database/error.html\*(C'\fR template might look like this:
.PP
.Vb 2
\& Database Error
\& A database error has occurred: [% error.info %]
.Ve
.PP
You can also specify a \f(CW\*(C`FINAL\*(C'\fR block. This is always processed
regardless of the outcome of the \f(CW\*(C`TRY\*(C'\fR and/or \f(CW\*(C`CATCH\*(C'\fR blocks. If an
exception is uncaught then the \f(CW\*(C`FINAL\*(C'\fR block is processed before jumping
to the enclosing block or returning to the caller.
.PP
.Vb 9
\& [% TRY %]
\& ...
\& [% CATCH this %]
\& ...
\& [% CATCH that %]
\& ...
\& [% FINAL %]
\& All done!
\& [% END %]
.Ve
.PP
The output from the \f(CW\*(C`TRY\*(C'\fR block is left intact up to the point where an
exception occurs. For example, this template:
.PP
.Vb 7
\& [% TRY %]
\& This gets printed
\& [% THROW food \*(Aqcarrots\*(Aq %]
\& This doesn\*(Aqt
\& [% CATCH food %]
\& culinary delights: [% error.info %]
\& [% END %]
.Ve
.PP
generates the following output:
.PP
.Vb 2
\& This gets printed
\& culinary delights: carrots
.Ve
.PP
The \f(CW\*(C`CLEAR\*(C'\fR directive can be used in a \f(CW\*(C`CATCH\*(C'\fR or \f(CW\*(C`FINAL\*(C'\fR block to clear
any output created in the \f(CW\*(C`TRY\*(C'\fR block.
.PP
.Vb 8
\& [% TRY %]
\& This gets printed
\& [% THROW food \*(Aqcarrots\*(Aq %]
\& This doesn\*(Aqt
\& [% CATCH food %]
\& [% CLEAR %]
\& culinary delights: [% error.info %]
\& [% END %]
.Ve
.PP
Output:
.PP
.Vb 1
\& culinary delights: carrots
.Ve
.PP
Exception types are hierarchical, with each level being separated by
the familiar dot operator. A \f(CW\*(C`DBI.connect\*(C'\fR exception is a more
specific kind of \f(CW\*(C`DBI\*(C'\fR error. Similarly, an \f(CW\*(C`example.error.barf\*(C'\fR is a
more specific kind of \f(CW\*(C`example.error\*(C'\fR type which itself is also a
\&\f(CW\*(C`example\*(C'\fR error.
.PP
A \f(CW\*(C`CATCH\*(C'\fR handler that specifies a general exception
type (such as \f(CW\*(C`DBI\*(C'\fR or \f(CW\*(C`example.error\*(C'\fR) will also catch more specific
types that have the same prefix as long as a more specific handler
isn't defined. Note that the order in which \f(CW\*(C`CATCH\*(C'\fR handlers are
defined is irrelevant; a more specific handler will always catch an
exception in preference to a more generic or default one.
.PP
.Vb 10
\& [% TRY %]
\& ...
\& [% CATCH DBI ;
\& INCLUDE database/error.html ;
\& CATCH DBI.connect ;
\& INCLUDE database/connect.html ;
\& CATCH ;
\& INCLUDE error.html ;
\& END
\& %]
.Ve
.PP
In this example, a \f(CW\*(C`DBI.connect\*(C'\fR error has it's own handler, a more general
\&\f(CW\*(C`DBI\*(C'\fR block is used for all other \f(CW\*(C`DBI\*(C'\fR or \f(CW\*(C`DBI.*\*(C'\fR errors and a default
handler catches everything else.
.PP
Exceptions can be raised in a template using the \f(CW\*(C`THROW\*(C'\fR directive. The
first parameter is the exception type which doesn't need to be quoted
(but can be, it's the same as \f(CW\*(C`INCLUDE\*(C'\fR) followed by the relevant error
message which can be any regular value such as a quoted string,
variable, etc.
.PP
.Vb 3
\& [% THROW food "Missing ingredients: $recipe.error" %]
\& [% THROW user.login \*(Aqno user id: please login\*(Aq %]
\& [% THROW $myerror.type "My Error: $myerror.info" %]
.Ve
.PP
It's also possible to specify additional positional or named
parameters to the \f(CW\*(C`THROW\*(C'\fR directive if you want to pass more than
just a simple message back as the error info field.
.PP
.Vb 1
\& [% THROW food \*(Aqeggs\*(Aq \*(Aqflour\*(Aq msg=\*(AqMissing Ingredients\*(Aq %]
.Ve
.PP
In this case, the error \f(CW\*(C`info\*(C'\fR field will be a hash array containing the
named arguments and an \f(CW\*(C`args\*(C'\fR item which contains a list of the positional
arguments.
.PP
.Vb 5
\& type => \*(Aqfood\*(Aq,
\& info => {
\& msg => \*(AqMissing Ingredients\*(Aq,
\& args => [\*(Aqeggs\*(Aq, \*(Aqflour\*(Aq],
\& }
.Ve
.PP
In addition to specifying individual positional arguments as
\&\f(CW\*(C`[% error.info.args.n %]\*(C'\fR, the \f(CW\*(C`info\*(C'\fR hash contains keys directly
pointing to the positional arguments, as a convenient shortcut.
.PP
.Vb 1
\& [% error.info.0 %] # same as [% error.info.args.0 %]
.Ve
.PP
Exceptions can also be thrown from Perl code which you've bound to
template variables, or defined as a plugin or other extension. To
raise an exception, call \f(CW\*(C`die()\*(C'\fR passing a reference to a
Template::Exception object as the argument. This will then be caught
by any enclosing \f(CW\*(C`TRY\*(C'\fR blocks from where the code was called.
.PP
.Vb 9
\& use Template::Exception;
\& ...
\& my $vars = {
\& foo => sub {
\& # ... do something ...
\& die Template::Exception\->new(\*(Aqmyerr.naughty\*(Aq,
\& \*(AqBad, bad error\*(Aq);
\& },
\& };
.Ve
.PP
Template:
.PP
.Vb 6
\& [% TRY %]
\& [% foo %]
\& [% CATCH myerr ;
\& "Error: $error" ;
\& END
\& %]
.Ve
.PP
Output:
.PP
.Vb 1
\& Error: myerr.naughty error \- Bad, bad error
.Ve
.PP
The \f(CW\*(C`info\*(C'\fR field can also be a reference to another object or data
structure, if required.
.PP
.Vb 4
\& die Template::Exception\->new(\*(Aqmyerror\*(Aq, {
\& module => \*(Aqfoo.pl\*(Aq,
\& errors => [ \*(Aqbad permissions\*(Aq, \*(Aqnaughty boy\*(Aq ],
\& });
.Ve
.PP
Later, in a template:
.PP
.Vb 8
\& [% TRY %]
\& ...
\& [% CATCH myerror %]
\& [% error.info.errors.size or \*(Aqno\*(Aq;
\& error.info.errors.size == 1 ? \*(Aq error\*(Aq : \*(Aq errors\*(Aq %]
\& in [% error.info.module %]:
\& [% error.info.errors.join(\*(Aq, \*(Aq) %].
\& [% END %]
.Ve
.PP
Generating the output:
.PP
.Vb 2
\& 2 errors in foo.pl:
\& bad permissions, naughty boy.
.Ve
.PP
You can also call \f(CW\*(C`die()\*(C'\fR with a single string, as is common in much
existing Perl code. This will automatically be converted to an
exception of the '\f(CW\*(C`undef\*(C'\fR' type (that's the literal string '\f(CW\*(C`undef\*(C'\fR',
not the undefined value). If the string isn't terminated with a
newline then Perl will append the familiar \f(CW" at $file line $line"\fR
message.
.PP
.Vb 4
\& sub foo {
\& # ... do something ...
\& die "I\*(Aqm sorry, Dave, I can\*(Aqt do that\en";
\& }
.Ve
.PP
If you're writing a plugin, or some extension code that has the current
Template::Context in scope (you can safely skip this section if this means
nothing to you) then you can also raise an exception by calling the context
\&\fBthrow()\fR method. You can pass it an
Template::Exception object reference, a pair of \f(CW\*(C`($type, $info)\*(C'\fR
parameters or just an \f(CW$info\fR string to create an exception of '\f(CW\*(C`undef\*(C'\fR' type.
.PP
.Vb 3
\& $context\->throw($e); # exception object
\& $context\->throw(\*(AqDenied\*(Aq); # \*(Aqundef\*(Aq type
\& $context\->throw(\*(Aquser.passwd\*(Aq, \*(AqBad Password\*(Aq);
.Ve
.SS "\s-1NEXT\s0"
.IX Subsection "NEXT"
The \f(CW\*(C`NEXT\*(C'\fR directive can be used to start the next iteration of a \f(CW\*(C`FOREACH\*(C'\fR
or \f(CW\*(C`WHILE\*(C'\fR loop.
.PP
.Vb 4
\& [% FOREACH user IN users %]
\& [% NEXT IF user.isguest %]
\& Name: [% user.name %] Email: [% user.email %]
\& [% END %]
.Ve
.SS "\s-1LAST\s0"
.IX Subsection "LAST"
The \f(CW\*(C`LAST\*(C'\fR directive can be used to prematurely exit a \f(CW\*(C`FOREACH\*(C'\fR or \f(CW\*(C`WHILE\*(C'\fR
loop.
.PP
.Vb 4
\& [% FOREACH user IN users %]
\& Name: [% user.name %] Email: [% user.email %]
\& [% LAST IF some.condition %]
\& [% END %]
.Ve
.PP
\&\f(CW\*(C`BREAK\*(C'\fR can also be used as an alias for \f(CW\*(C`LAST\*(C'\fR.
.SS "\s-1RETURN\s0"
.IX Subsection "RETURN"
The \f(CW\*(C`RETURN\*(C'\fR directive can be used to stop processing the current template
and return to the template from which it was called, resuming processing at
the point immediately after the \f(CW\*(C`INCLUDE\*(C'\fR, \f(CW\*(C`PROCESS\*(C'\fR or \f(CW\*(C`WRAPPER\*(C'\fR
directive. If there is no enclosing template then the Template
\&\fBprocess()\fR method will return to the calling code with a
true value.
.PP
.Vb 3
\& Before
\& [% INCLUDE half_wit %]
\& After
\&
\& [% BLOCK half_wit %]
\& This is just half...
\& [% RETURN %]
\& ...a complete block
\& [% END %]
.Ve
.PP
Output:
.PP
.Vb 3
\& Before
\& This is just half...
\& After
.Ve
.SS "\s-1STOP\s0"
.IX Subsection "STOP"
The \f(CW\*(C`STOP\*(C'\fR directive can be used to indicate that the processor should stop
gracefully without processing any more of the template document. This is a
planned stop and the Template \fBprocess()\fR method will
return a \fBtrue\fR value to the caller. This indicates that the template was
processed successfully according to the directives within it.
.PP
.Vb 4
\& [% IF something.terrible.happened %]
\& [% INCLUDE fatal/error.html %]
\& [% STOP %]
\& [% END %]
\&
\& [% TRY %]
\& [% USE DBI(mydsn) %]
\& ...
\& [% CATCH DBI.connect %]
\& Cannot connect to the database: [% error.info %]
\&
\& We apologise for the inconvenience.
\&
\& [% INCLUDE footer %]
\& [% STOP %]
\& [% END %]
.Ve
.SS "\s-1CLEAR\s0"
.IX Subsection "CLEAR"
The \f(CW\*(C`CLEAR\*(C'\fR directive can be used to clear the output buffer for the current
enclosing block. It is most commonly used to clear the output generated
from a \f(CW\*(C`TRY\*(C'\fR block up to the point where the error occurred.
.PP
.Vb 8
\& [% TRY %]
\& blah blah blah # this is normally left intact
\& [% THROW some \*(Aqerror\*(Aq %] # up to the point of error
\& ...
\& [% CATCH %]
\& [% CLEAR %] # clear the TRY output
\& [% error %] # print error string
\& [% END %]
.Ve
.SH "Miscellaneous"
.IX Header "Miscellaneous"
.SS "\s-1META\s0"
.IX Subsection "META"
The \f(CW\*(C`META\*(C'\fR directive allows simple metadata items to be defined within a
template. These are evaluated when the template is parsed and as such may only
contain simple values (e.g. it's not possible to interpolate other variables
values into \f(CW\*(C`META\*(C'\fR variables).
.PP
.Vb 5
\& [% META
\& title = \*(AqThe Cat in the Hat\*(Aq
\& author = \*(AqDr. Seuss\*(Aq
\& version = 1.23
\& %]
.Ve
.PP
The \f(CW\*(C`template\*(C'\fR variable contains a reference to the main template
being processed. These metadata items may be retrieved as attributes
of the template.
.PP
.Vb 2
\& [% template.title %]
\& [% template.author %]
.Ve
.PP
The \f(CW\*(C`name\*(C'\fR and \f(CW\*(C`modtime\*(C'\fR metadata items are automatically defined for each
template to contain its name and modification time in seconds since the epoch.
.PP
.Vb 4
\& [% USE date %] # use Date plugin to format time
\& ...
\& [% template.name %] last modified
\& at [% date.format(template.modtime) %]
.Ve
.PP
The \f(CW\*(C`PRE_PROCESS\*(C'\fR and \f(CW\*(C`POST_PROCESS\*(C'\fR options allow common headers and
footers to be added to all templates. The \f(CW\*(C`template\*(C'\fR reference is
correctly defined when these templates are processed, allowing headers
and footers to reference metadata items from the main template.
.PP
.Vb 4
\& $template = Template\->new({
\& PRE_PROCESS => \*(Aqheader\*(Aq,
\& POST_PROCESS => \*(Aqfooter\*(Aq,
\& });
\&
\& $template\->process(\*(Aqcat_in_hat\*(Aq);
.Ve
.PP
header:
.PP
.Vb 5
\&
\&
\& [% template.title %]
\&
\&
.Ve
.PP
cat_in_hat:
.PP
.Vb 6
\& [% META
\& title = \*(AqThe Cat in the Hat\*(Aq
\& author = \*(AqDr. Seuss\*(Aq
\& version = 1.23
\& year = 2000
\& %]
\&
\& The cat in the hat sat on the mat.
.Ve
.PP
footer:
.PP
.Vb 4
\&
\& © [% template.year %] [% template.author %]
\&
\&
.Ve
.PP
The output generated from the above example is:
.PP
.Vb 10
\&
\&
\& The Cat in the Hat
\&
\&
\& The cat in the hat sat on the mat.
\&
\& © 2000 Dr. Seuss
\&
\&
.Ve
.SS "\s-1TAGS\s0"
.IX Subsection "TAGS"
The \f(CW\*(C`TAGS\*(C'\fR directive can be used to set the \f(CW\*(C`START_TAG\*(C'\fR and \f(CW\*(C`END_TAG\*(C'\fR values
on a per-template file basis.
.PP
.Vb 1
\& [% TAGS <+ +> %]
\&
\& <+ INCLUDE header +>
.Ve
.PP
The \s-1TAGS\s0 directive may also be used to set a named \f(CW\*(C`TAG_STYLE\*(C'\fR
.PP
.Vb 2
\& [% TAGS html %]
\&
.Ve
.PP
See the \s-1TAGS\s0 and \s-1TAG_STYLE\s0
configuration options for further details.
.SS "\s-1DEBUG\s0"
.IX Subsection "DEBUG"
The \f(CW\*(C`DEBUG\*(C'\fR directive can be used to enable or disable directive debug
messages within a template. The \f(CW\*(C`DEBUG\*(C'\fR configuration option must be
set to include \f(CW\*(C`DEBUG_DIRS\*(C'\fR for the \f(CW\*(C`DEBUG\*(C'\fR directives to have any effect.
If \f(CW\*(C`DEBUG_DIRS\*(C'\fR is not set then the parser will automatically ignore and
remove any \f(CW\*(C`DEBUG\*(C'\fR directives.
.PP
The \f(CW\*(C`DEBUG\*(C'\fR directive can be used with an \f(CW\*(C`on\*(C'\fR or \f(CW\*(C`off\*(C'\fR parameter to
enable or disable directive debugging messages from that point
forward. When enabled, the output of each directive in the generated
output will be prefixed by a comment indicate the file, line and
original directive text.
.PP
.Vb 4
\& [% DEBUG on %]
\& directive debugging is on (assuming DEBUG option is set true)
\& [% DEBUG off %]
\& directive debugging is off
.Ve
.PP
The \f(CW\*(C`format\*(C'\fR parameter can be used to change the format of the debugging
message.
.PP
.Vb 1
\& [% DEBUG format \*(Aq\*(Aq %]
.Ve