GENERALTAGSYNTAX
A generic HTML::Template tag that is supported by HTML::Template::Pro looks like <TMPL_SOMETHING A="B"
[C="D" ...]>. Tags are case-insensitve: <tmpl_something a="B" [c="D" ...]> is acceptable. Single quotes
can be used, <TMPL_SOMETHING A='B' [C='D' ...]> quotes can be omitted, <TMPL_SOMETHING A=B ... > and
option name could be often guessed as in <TMPL_SOMETHING B>.
template tags could be decorated as html comments <!-- TMPL_SOMETHING A="B" -->
Also, as HTML::Template::Pro extension (starting from version 0.90), template tags could also be
decorated as xml <TMPL_SOMETHING A="B" />
See NOTES.
TMPL_VAR
<TMPL_VAR NAME="PARAMETER_NAME">
The <TMPL_VAR> tag is very simple. For each <TMPL_VAR> tag in the template you call
$template->param(PARAMETER_NAME => "VALUE"). When the template is output the <TMPL_VAR> is replaced with
the VALUE text you specified. If you don't set a parameter it just gets skipped in the output.
Optionally you can use the "ESCAPE=HTML" option in the tag to indicate that you want the value to be
HTML-escaped before being returned from output (the old ESCAPE=1 syntax is still supported). This means
that the ", <, >, and & characters get translated into ", <, > and & respectively. This
is useful when you want to use a TMPL_VAR in a context where those characters would cause trouble.
Example:
<input name=param type=text value="<TMPL_VAR NAME="PARAM">">
If you called param() with a value like sam"my you'll get in trouble with HTML's idea of a double-quote.
On the other hand, if you use ESCAPE=HTML, like this:
<input name=param type=text value="<TMPL_VAR ESCAPE=HTML NAME="PARAM">">
You'll get what you wanted no matter what value happens to be passed in for param. You can also write
ESCAPE="HTML", ESCAPE='HTML' and ESCAPE='1'.
"ESCAPE=0" and "ESCAPE=NONE" turn off escaping, which is the default behavior.
There is also the "ESCAPE=URL" option which may be used for VARs that populate a URL. It will do URL
escaping, like replacing ' ' with '+' and '/' with '%2F'.
There is also the "ESCAPE=JS" option which may be used for VARs that need to be placed within a
Javascript string. All \n, \r, ' and " characters are escaped.
You can assign a default value to a variable with the DEFAULT attribute. For example, this will output
"the devil gave me a taco" if the "who" variable is not set.
The <TMPL_VAR NAME=WHO DEFAULT=devil> gave me a taco.
TMPL_LOOP
<TMPL_LOOP NAME="LOOP_NAME"> ... </TMPL_LOOP>
The <TMPL_LOOP> tag is a bit more complicated than <TMPL_VAR>. The <TMPL_LOOP> tag allows you to delimit
a section of text and give it a name. Inside this named loop you place <TMPL_VAR>s. Now you pass to
param() a list (an array ref) of parameter assignments (hash refs) for this loop. The loop iterates over
the list and produces output from the text block for each pass. Unset parameters are skipped. Here's an
example:
In the template:
<TMPL_LOOP NAME=EMPLOYEE_INFO>
Name: <TMPL_VAR NAME=NAME> <br>
Job: <TMPL_VAR NAME=JOB> <p>
</TMPL_LOOP>
In the script:
$template->param(EMPLOYEE_INFO => [
{ name => 'Sam', job => 'programmer' },
{ name => 'Steve', job => 'soda jerk' },
]
);
print $template->output();
The output in a browser:
Name: Sam
Job: programmer
Name: Steve
Job: soda jerk
As you can see above the <TMPL_LOOP> takes a list of variable assignments and then iterates over the loop
body producing output.
Often you'll want to generate a <TMPL_LOOP>'s contents programmatically. Here's an example of how this
can be done (many other ways are possible!):
# a couple of arrays of data to put in a loop:
my @words = qw(I Am Cool);
my @numbers = qw(1 2 3);
my @loop_data = (); # initialize an array to hold your loop
while (@words and @numbers) {
my %row_data; # get a fresh hash for the row data
# fill in this row
$row_data{WORD} = shift @words;
$row_data{NUMBER} = shift @numbers;
# the crucial step - push a reference to this row into the loop!
push(@loop_data, \%row_data);
}
# finally, assign the loop data to the loop param, again with a
# reference:
$template->param(THIS_LOOP => \@loop_data);
The above example would work with a template like:
<TMPL_LOOP NAME="THIS_LOOP">
Word: <TMPL_VAR NAME="WORD"> <br>
Number: <TMPL_VAR NAME="NUMBER"> <p>
</TMPL_LOOP>
It would produce output like:
Word: I
Number: 1
Word: Am
Number: 2
Word: Cool
Number: 3
<TMPL_LOOP>s within <TMPL_LOOP>s are fine and work as you would expect. If the syntax for the param()
call has you stumped, here's an example of a param call with one nested loop:
$template->param(LOOP => [
{ name => 'Bobby',
nicknames => [
{ name => 'the big bad wolf' },
{ name => 'He-Man' },
],
},
],
);
Basically, each <TMPL_LOOP> gets an array reference. Inside the array are any number of hash references.
These hashes contain the name=>value pairs for a single pass over the loop template.
Inside a <TMPL_LOOP>, the only variables that are usable are the ones from the <TMPL_LOOP>. The
variables in the outer blocks are not visible within a template loop. For the computer-science geeks
among you, a <TMPL_LOOP> introduces a new scope much like a perl subroutine call. If you want your
variables to be global you can use 'global_vars' option to new() described below.
TMPL_INCLUDE
<TMPL_INCLUDE NAME="filename.tmpl">
<TMPL_INCLUDE EXPR="function_call, variable, expression" DEFAULT='some_file'>
This tag includes a template directly into the current template at the point where the tag is found. The
included template contents are used exactly as if its contents were physically included in the master
template.
The file specified can be an absolute path (beginning with a '/' under Unix, for example). If it isn't
absolute, the path to the enclosing file is tried first. After that the path in the environment variable
HTML_TEMPLATE_ROOT is tried, if it exists. Next, the "path" option is consulted, first as-is and then
with HTML_TEMPLATE_ROOT prepended if available. As a final attempt, the filename is passed to open()
directly. See below for more information on HTML_TEMPLATE_ROOT and the "path" option to new().
As a protection against infinitly recursive includes, an arbitrary limit of 10 levels deep is imposed.
You can alter this limit with the "max_includes" option. See the entry for the "max_includes" option
below for more details.
For the <TMPL_INCLUDE EXPR=".."> see "INCLUDE extension to Expr" for more details.
TMPL_IF
<TMPL_IF NAME="PARAMETER_NAME"> ... </TMPL_IF>
The <TMPL_IF> tag allows you to include or not include a block of the template based on the value of a
given parameter name. If the parameter is given a value that is true for Perl - like '1' - then the
block is included in the output. If it is not defined, or given a false value - like '0' - then it is
skipped. The parameters are specified the same way as with TMPL_VAR.
Example Template:
<TMPL_IF NAME="BOOL">
Some text that only gets displayed if BOOL is true!
</TMPL_IF>
Now if you call $template->param(BOOL => 1) then the above block will be included by output.
<TMPL_IF> </TMPL_IF> blocks can include any valid HTML::Template construct - VARs and LOOPs and other
IF/ELSE blocks. Note, however, that intersecting a <TMPL_IF> and a <TMPL_LOOP> is invalid.
Not going to work:
<TMPL_IF BOOL>
<TMPL_LOOP SOME_LOOP>
</TMPL_IF>
</TMPL_LOOP>
If the name of a TMPL_LOOP is used in a TMPL_IF, the IF block will output if the loop has at least one
row. Example:
<TMPL_IF LOOP_ONE>
This will output if the loop is not empty.
</TMPL_IF>
<TMPL_LOOP LOOP_ONE>
....
</TMPL_LOOP>
WARNING: Much of the benefit of HTML::Template is in decoupling your Perl and HTML. If you introduce
numerous cases where you have TMPL_IFs and matching Perl if()s, you will create a maintenance problem in
keeping the two synchronized. I suggest you adopt the practice of only using TMPL_IF if you can do so
without requiring a matching if() in your Perl code.
TMPL_ELSIF
<TMPL_IF NAME="PARAMETER_NAME1"> ...
<TMPL_ELSIF NAME="PARAMETER_NAME2"> ...
<TMPL_ELSIF NAME="PARAMETER_NAME3"> ...
<TMPL_ELSE> ... </TMPL_IF>
WARNING: TMPL_ELSIF is a HTML::Template::Pro extension! It is not supported in HTML::Template (as of
2.9).
TMPL_ELSE
<TMPL_IF NAME="PARAMETER_NAME"> ... <TMPL_ELSE> ... </TMPL_IF>
You can include an alternate block in your TMPL_IF block by using TMPL_ELSE. NOTE: You still end the
block with </TMPL_IF>, not </TMPL_ELSE>!
Example:
<TMPL_IF BOOL>
Some text that is included only if BOOL is true
<TMPL_ELSE>
Some text that is included only if BOOL is false
</TMPL_IF>
TMPL_UNLESS
<TMPL_UNLESS NAME="PARAMETER_NAME"> ... </TMPL_UNLESS>
This tag is the opposite of <TMPL_IF>. The block is output if the CONTROL_PARAMETER is set false or not
defined. You can use <TMPL_ELSE> with <TMPL_UNLESS> just as you can with <TMPL_IF>.
Example:
<TMPL_UNLESS BOOL>
Some text that is output only if BOOL is FALSE.
<TMPL_ELSE>
Some text that is output only if BOOL is TRUE.
</TMPL_UNLESS>
If the name of a TMPL_LOOP is used in a TMPL_UNLESS, the UNLESS block output if the loop has zero rows.
<TMPL_UNLESS LOOP_ONE>
This will output if the loop is empty.
</TMPL_UNLESS>
<TMPL_LOOP LOOP_ONE>
....
</TMPL_LOOP>
NOTES
HTML::Template's tags are meant to mimic normal HTML tags. However, they are allowed to "break the
rules". Something like:
<img src="<TMPL_VAR IMAGE_SRC>">
is not really valid HTML, but it is a perfectly valid use and will work as planned.
The "NAME=" in the tag is optional, although for extensibility's sake I recommend using it. Example -
"<TMPL_LOOP LOOP_NAME>" is acceptable.
If you're a fanatic about valid HTML and would like your templates to conform to valid HTML syntax, you
may optionally type template tags in the form of HTML comments. This may be of use to HTML authors who
would like to validate their templates' HTML syntax prior to HTML::Template processing, or who use DTD-
savvy editing tools.
<!-- TMPL_VAR NAME=PARAM1 -->
In order to realize a dramatic savings in bandwidth, the standard (non-comment) tags will be used
throughout this documentation.