Overview
This page provides a description of the templating language used by htmltmpl.
The syntax is very similar to that of HTML::Template, nevertheless some changes have been made and some new features were added.
HTML::Template compatibility
Templates created for HTML::Template can be used with this engine if they do not violate the character case rules of htmltmpl.
WARNING: Template statements must always be in uppercase. Variable names must always be in lowercase. Loop names must be in lowercase and capitalized.
WARNING: All included templates must be located in a directory named 'inc'. This directory must be a subdirectory of the directory in which the main template file is located. You must refer to these templates to be included only by their filename, ie. without the 'inc' part of the path.
The engine offers all the features of HTML::Template except:
- The IPC shared cache.
The engine also offers some additional features:
-
Gettext support for the creation of multilingual web applications.
-
Extended conditions for TMPL_IF, TMPL_UNLESS and TMPL_ELSEIF. These can be used to compare a variable with a fixed string or with a numeric value, which is useful for branching.
-
TMPL_ELSEIF was added.
-
Special comments in the form of "### some comment" can be added to the templates. These comments are removed when the templates are processed.
-
Precompiled versions of the templates can be saved on disk to increase performance significantly. This feature greatly reduces the need for caching of any sort.
-
Multipart templates can be created using the <TMPL_BOUNDARY> directive. Multipart templates are useful when you need to process and output a part of the template before all the data needed to process the whole template are ready.
-
Additional loop context variables.
- __PASS__
- __PASSTOTAL__
- __EVERY__x
-
Loop identifiers used in <TMPL_VAR> statements produce a total number of passes of the corresponding loop.
-
You can override the global_vars setting on a per-variable basis using a new 'GLOBAL' parameter.
-
All variables are by default automatically HTML escaped. This can be disabled by setting the 'html_escape' parameter to false.
Syntax overview
Statements
The control statements of the templating language look like HTML tags. These can be written in two ways:
- <TMPL_VAR>
- <!-- TMPL_VAR -->
There must be exactly one space after the opening "<!--" and before the closing "-->" if you use the longer form.
All statements except TMPL_VAR and the conditionals (TMPL_IF etc.) should be on a separate line.
All tabs and spaces on a line in front of a statement are removed if there are no other characters except tabs and spaces between the beginning of the line and the statement.
A trailing newline following a statement is removed if there are no other characters between the newline and the statement.
The white-space removing described above is a Good Thing, because it keeps the HTML nicely formatted, especially when loops are involved. If you want to preserve the newline after a statement, just add a space or a tab after that statement.
The statements do not need to follow HTML validity rules. For example, the following use of TMPL_VAR is valid:
<img src="<TMPL_VAR image>" />
Unrecognized TMPL_* statements are detected and a TemplateError is raised when one is found.
Statements must be in uppercase, for example "TMPL_VAR", because it improves the readability of the templates. It also makes the statements easy to distinguish from normal XHTML tags that are always in lowercase.
Templates must not contain the '\0' character (ASCII code zero).
Parameters of the statements
Parameters can be written in two ways:
- with double quotes: <TMPL_VAR myvar ESCAPE="HTML">
- without double quotes: <TMPL_VAR myvar ESCAPE=HTML>
There must not be any space between the "=" character and the name or the value of the parameter.
Parameter names must be in uppercase: ESCAPE="HTML".
Predefined special values of parameters (like for example the "HTML", "URL" and "NONE" values of the ESCAPE parameter) must be in uppercase.
The parameter names and values can contain only alphanumeric characters (non-locale) plus a few additional characters: dash, dot, underscore, colon, slash, backslash. They must NOT contain any spaces.
Identifiers
There are three types of identifiers:
- names of variables
- names of loops
- filenames of included templates
Names of loops and variables can contain ASCII (non-locale) alphanumeric characters, underscores and dashes. The names of loops and variables are further restricted by the character case rules described below.
Template filenames in TMPL_INCLUDE statements can contain only the same characters that are allowed in the values of parameters (see above). They must NOT contain any spaces.
The minimum length of an identifier is one character. The names of variables and loops can be specified in two ways:
- as bare-words: <TMPL_VAR myvar>
- as 'NAME' parameters: <TMPL_VAR NAME="myvar">
The following character case rules apply to the names of variables and loops:
- Variable names must be in lowercase: myvar
- Loop names must be capitalized and in lowercase: Myloop
Valid statements and parameters
| TMPL_INCLUDE | NAME |
| TMPL_VAR | NAME, ESCAPE, GLOBAL |
| TMPL_IF | a condition |
| TMPL_UNLESS | a condition |
| TMPL_ELSE | no parameters |
| TMPL_ELSEIF | a condition |
| /TMPL_IF | no parameters |
| /TMPL_UNLESS | no parameters |
| TMPL_LOOP | NAME |
| /TMPL_LOOP | no parameters |
| TMPL_BOUNDARY | no parameters |
| TMPL_STATIC | NAME, ESCAPE |
Template comments
Comments are in the form of "### some comment". Everything that follows these four characters - "### " - is removed before the template is processed. The trailing space in "### " IS significant. Comments can be disabled using the 'comments' parameter.
Examples:
<TMPL_VAR myname> ### first comment
<TMPL_VAR hisname> ### second comment
Statements
Template inclusion
The <TMPL_INCLUDE> statement includes a template directly into the current template at the point where the statement is located. The content of the included template is used exactly as if it were written right in the including template.
All included templates must be located in a directory named 'inc', which must be a subdirectory of the directory in which the main template file is located. You must refer to these templates only by their filename, without the 'inc' component of the path.
Examples:
<TMPL_INCLUDE header.tmpl>
<TMPL_INCLUDE NAME="header.tmpl">
Variables
TODO
The variables defined using TMPL_VAR statements are replaced with values associated with them by the set() method of the TemplateProcessor.
Escaping of variables
All variables are automatically HTML escaped, which can be disabled using the 'html_escape' parameter. The escaping of variables can also be specified per-variable using the ESCAPE parameter that overrides the default escaping setting. It takes three values:
- HTML : enable HTML escaping
- URL : enable URL + HTML escaping (first URL-escapes, then HTML-escapes)
- WAP : enable WML escaping (for WAP variables: "$" ==> "$$")
- NONE : disable escaping
The ESCAPE parameter can be used with both TMPL_VAR and TMPL_STATIC statements. TMPL_STATIC variables are by default always HTML-escaped.
Global look-up of variables
All variables that are inside a loop are local to that loop. If you want to reference a "global" variable from within the loop you must either enable the 'global_vars' parameter or use the GLOBAL parameter to override the 'global_vars' setting on a per variable basis.
Examples:
<TMPL_VAR name>
<TMPL_VAR NAME="city">
<TMPL_VAR NAME="text1" ESCAPE="HTML">
<TMPL_VAR NAME="text2" ESCAPE="NONE" GLOBAL="0">
<TMPL_VAR address GLOBAL="1">
<!-- TMPL_VAR test ESCAPE=URL -->
Conditionals
The TMPL_IF, /TMPL_IF, TMPL_ELSE, TMPL_ELSEIF, TMPL_UNLESS and /TMPL_UNLESS statements are conditionals. They mark the start and the end of a block that is added to the output only if the condition evaluates to true. Names of variables and loops can be used in the condition. Conditional blocks may contain other nested conditional blocks.
If the name of a loop is used in the condition, then the condition is true if the content of the loop would be added to the output at least once.
Examples:
<TMPL_IF myvar>
This block appears in the output if myvar is true.
<TMPL_ELSE>
This block appears in the output if myvar is false.
</TMPL_IF>
<TMPL_UNLESS hisvar>
This block appears in the output if hisvar is false.
<TMPL_ELSE>
This block appears in the output if hisvar is true.
</TMPL_UNLESS>
<TMPL_IF error>
There was an error.
<TMPL_ELSE>
Operation completed successfully.
</TMPL_IF>
<TMPL_IF action == forward>
Forwarding was set.
<TMPL_ELSEIF action == notify>
Notification was set.
<TMPL_ELSEIF action == autoreply>
Autoreply was set.
<TMPL_ELSE>
No action.
</TMPL_IF>
Extended TMPL_IF, TMPL_UNLESS and TMPL_ELSEIF conditions
Extended conditions were added when five years of experience with the templates showed that without them some very common coding tasks were quite awkward. The syntax is:
<TMPL_IF variable_name operator condition_value>
There are two operators: == !=
The condition_value may be either a string or a number. It must NOT be enclosed in quotes, even when it is a string. The extended conditions are very useful for working with RADIO, CHECKBOX and SELECT form elements:
<select name="antispam" size="1">
<option <TMPL_IF antispam == active>checked</TMPL_IF>>active</option>
<option <TMPL_IF antispam == low>checked</TMPL_IF>>low</option>
<option <TMPL_IF antispam == disabled>checked</TMPL_IF>>disabled</option>
</select>
Loops
TODO
The TMPL_LOOP and /TMPL_LOOP statements mark the start and the end of a block that is added to the output once for each mapping in the list of mappings associated with the corresponding loop.
Loops can contain other nested loops. Every loop introduces its own namespace (scope) for variables. Variables located inside a loop cannot reference variables located outside the loop unless the 'global_vars' parameter is true, or unless this parameter is overridden for this particular variable using the 'GLOBAL' parameter of the corresponding TMPL_VAR statement.
Loop names used as variables in TMPL_VAR statements produce the total number of passes of the corresponding loop.
examples
<TMPL_LOOP Myloop>
This block appears in the output
once for every pass of the loop.
<TMPL_VAR myvar> ### Local variable.
</TMPL_LOOP>
Magic loop variables
Magic context variables are automatically defined in every loop. They can be used the same way as normal variables. Their names always begin with two underscores. The values of these variables are always integers (true = 1, false = 0).
The following list sums up all the recognized magic variables. Any other variable name that begins with two underscores is invalid. The TemplateError exception is raised when such a variable name is found.
__FIRST__
This variable is true if the current pass is the first pass.
__LAST__
This variable is true if the current pass is the last pass.
__INNER__
This variable is true if the current pass is neither the first nor the last.
__ODD__
This variable is true if the number of the current pass is odd. That means it's true in the first, third, fifth, seventh ..... pass.
__PASS__
The value of this variable is the number of the current pass. The passes are counted from one. The value of this variable is one in the first pass, two in the second pass etc.
__PASSTOTAL__
The value of this variable is the total number of passes in the current loop.
__EVERY__x
Where 'x' must be an integer. It can have multiple digits. This variable is true if the number of the current pass modulo 'x' equals zero. The variable is never true in the first or in the last pass, even if the condition above is true in such a pass. This variable can be used to put separators between every 'x' items of a list.
Multipart templates
Multipart templates can be created using the <TMPL_BOUNDARY> directive. This directive takes no parameters.
Multipart templates are useful when you need to process and add to the output a part of the template before all the data needed to process the whole template is available.
This can be used to improve the perceived responsiveness of a web application by sending the top part of the page to the client before the web application, for example, makes a slow query to the database and generates the rest of the page using the results of that query. Keep in mind that you probably will have to flush the output stream to achieve the desired effect. This can usually be done by calling sys.stdout.flush() in Python or flush() in PHP.
Multipart templates must follow this rule: all the parts must be syntactically valid templates. That means that the boundaries between the parts must not be located inside a conditional block or inside a loop.
The boundaries are processed after all template inclusions are processed. It is possible to put the boundaries in included templates, though it is not recommended.
Please consult the API documentation of the TemplateProcessor.process() method to find out how to use the multipart templates in your application.
examples
This is part one.
<TMPL_BOUNDARY>
This is part two.
<TMPL_BOUNDARY>
This is part three.
Static template variables (TMPL_STATIC)
Static template variables are similar to TMPL_VARs, but are intended to represent static values that never change. They can be useful when one string appears many times in a template, or in various different templates.
Static variables are in some way similar to TMPL_INCLUDE statements, except that they are processed much faster and are typically used for shorter strings.
Static variables are often used to emulate CSS classes when you cannot use CSS due to browser compatibility problems. You can, for example, define a static variable called "lightred2" and use it in all the places where you need to assign that color. This provides an easy way to change it later in one place.
Static variables are resolved during the compilation phase and cannot be changed without the recompilation of the template.
You can use the static_data() method of the TemplataManager class to define static variables. If you want to keep your static variables in a separate file you should also check out the watch_files() method. This method can be used to monitor any changes made to that file and thus force the recompilation of the template when the value of the static variable changes.
Example
template.tmpl
<html>
<head>
<title><TMPL_VAR title></title>
</head>
<body>
<h1>Customers:</h1>
<p>
Total: <TMPL_VAR Customers>
</p>
### this comment will be removed
<table>
<TMPL_LOOP Customers>
<tr>
<TMPL_IF new>
<td>new customer</td>
<TMPL_ELSE>
<td>old customer</td>
</TMPL_IF>
<td><TMPL_VAR __PASS__></td>
<td><TMPL_VAR name></td>
<td><TMPL_VAR city></td>
</tr>
</TMPL_LOOP>
</table>
</body>
</html>