The CT++ template language (2.8 version)

Contents

Templates

A template is a text file, that is marked-up using the CT++ template language. It used to separate content from presentation in web design.

A template can contain CT++ tags. All CT++ tags have HTML-like syntax and they start with TMPL_. Names of CT++ tags are case insensetive (for example, TMPL_var, tmpl_var, or TmPl_VaR).

CT++ supports the next tags: TMPL_var, TMPL_if, TMPL_elsif, TMPL_else, TMPL_unless, TMPL_foreach, TMPL_include, TMPL_comment, TMPL_block, TMPL_call, and TMPL_verbose.

Example of a template:

<!DOCTYPE html>
<TMPL_include 'includes/html_lang.tmpl'>
<TMPL_include 'includes/html_head.tmpl'>
    <link rel="stylesheet" href="/static/css/m.posts.css">
</head>
<body class="posts">
    <div id="body-wrapper" class="body-wrapper">
        <div id="content-wrapper" class="content-wrapper">
            <TMPL_include 'includes/header.tmpl'>
            <section role="main" class="content-column">
                <h1><TMPL_var _("Welcome to")> <TMPL_var project_name>, <TMPL_verbose>
                <TMPL_if logged>
                    <TMPL_var HTMLESCAPE(DEFAULT(user_info.name, user_info.username))>
                <TMPL_else>
                    <TMPL_var _("Anonymous")>
                </TMPL_if></h1>
                </TMPL_verbose>

                <TMPL_verbose>
                <TMPL_foreach users as user>
                    <h3><a class="user-page-link" href="/user/<TMPL_var URLESCAPE(user.username)>" title="
                        <TMPL_var HTMLESCAPE(DEFAULT(user.name, user.username))>">
                        <TMPL_var HTMLESCAPE(DEFAULT(user.name, user.username))>
                        </a></h3>
                </TMPL_foreach>
                </TMPL_verbose>

            </section>
            <TMPL_include 'includes/noscript_alert.tmpl'>
        </div>
    </div>
    <TMPL_include 'includes/footer.tmpl'>
</body>
</html>

Comments

Use the TMPL_comment tag to comment-out part of a template.

For example:

<TMPL_comment><h3>Hello, <TMPL_var username>!</h3></TMPL_comment>

Formatting

The TMPL_verbose tag removes white-space characters (space, form-feed, newline, carriage return, horizontal tab, and vertical tab) between CT++ tags.

For example:

<TMPL_verbose>
    foo: <TMPL_var foo> some text
    bar: <TMPL_var bar> baz: <TMPL_var baz> <TMPL_var spam>
</TMPL_verbose>

For instance, variables foo, bar, baz, and spam are respectively "{FOO}", "{BAR}", "{BAZ}", and "{SPAM}". The template would be rendered as:

foo:{FOO}some text
    bar:{BAR}baz:{BAZ}{SPAM}

Also, a dash could be used instead the TMPL_verbose tag:

foo: <TMPL_var foo-> some text
    bar: <-TMPL_var bar-> baz: <-TMPL_var baz-> <-TMPL_var spam>

There will same output.

Including

The TMPL_include tag loads another template within the template. The tag has the one attribute only. The attribute can't be a variable. It's a filename in quotes:

<TMPL_include "filename.tmpl">

It is impossible to break conditions and loops between templates.

Variables

The CT++ template engine evaluates variable and replaces it with the result. The TMPL_var tag is used for evaluating variables.

The types of variables are undefined variable, string, integer, floating-point number, mapping, and array. For undefined variables result is an empty string.

The TMPL_var evaluates expressions: variables, operators, and functions. For example:

<TMPL_var foo>
<TMPL_var (foo + bar + 1)>
<TMPL_var HTMLESCAPE(baz)>

Arrays

An array is a data type consisting of a collection of elements, each identified by one array index. The first element of the array is indexed by subscript of 0.

Examples:

<TMPL_var foo[0]>   <- foo must be an array!
<TMPL_var foo[bar]> <- bar must be an integer!

Mappings

A mapping is a data type composed of a collection of (key,value) pairs, such that each possible key appears at most once in the collection.

Examples:

<TMPL_var foo.key> = <TMPL_var foo["key"]> <- foo must be a mapping
<TMPL_var foo.bar.baz> <- the mapping foo has the key "bar" with mapping value, that has the key "baz"

Use a dot to access attributes of a variable.

Control flow

Choice

The TMPL_if tag and the TMPL_unless tag evaluate a condition. A condition can be variable, function calls, arithmetic and logic expressions. Arithmetic and logic expressions must be inside of parentheses.

Examples:

<TMPL_if foo>
    Some text with <TMPL_var foo>
</TMPL_if>

<TMPL_unless DEFINED(bar)>
    Some text
<TMPL_else>
    Some text with <TMPL_var bar>
</TMPL_unless>

<TMPL_if (x < 1)>
    eeny
<TMPL_elsif (x < 2)>
    meeny
<TMPL_elsif (x < 3)>
    miny
<TMPL_else>
    moe
</TMPL_if>

The following table summarizes the operator precedences, from highest precedence to lowest precedence:

Operators Assoc Description
(expression)   parentheses used for grouping
() LR parentheses used for a function call
. LR member selection
[] LR array/mapping element access
!, +, - RL logical not, unary plus, unary minus
*, /, mod, div LR multiplication and division
+, - LR addition and subtraction
<, <=, >, >= LR inequality relational
==, != LR equality relational
&& LR logical and
|| LR logical or

CT++ defines keywords to act as aliases for a number of operators: lt (<), le (<=), gt (>), ge (>=), eq (==), ne (!=), and (&&), or (||).

Loops

CT++ supports the TMPL_foreach only. It use an explicit iterator, in which the loop variable takes on each of the values in an array or a mapping.

An iterator has special attributes:

Attribute Description
__index__ index of array's element
__key__ key in mapping
__first__ "true" for first iteration
__last__ "true" for last iteration
__inner__ "true" if not first and not last iteration
__even__ "true" for even iteration
__odd__ "true" for odd iteration
__value__ value of element

Example of usage:

<TMPL_foreach array as a>
    value: <TMPL_var a> or <TMPL_var a.__value__>
    index: <TMPL_var a.__index__>
    <TMPL_if a.__first__>#first#</TMPL_if>
    <TMPL_if a.__even__>#even#<TMPL_else>#odd#</TMPL_if>
</TMPL_foreach>

<TMPL_foreach map as m>
    value: <TMPL_var m> or <TMPL_var m.__value__>
    key: <TMPL_var m.__key__>
    <TMPL_if m.__last__>#last#</TMPL_if>
</TMPL_foreach>

The TMPL_break tag breaks the iteration of loop:

<TMPL_verbose>
<TMPL_foreach LIST("a", "b", "c") as char>
    <TMPL_var char>
    <TMPL_if (char == "b")><TMPL_break></TMPL_if>
</TMPL_foreach>
</TMPL_verbose>

Output of the template is "ab".

Functions

CT++ has built-in functions, that is described in Library reference. CT++ tags, that support it: TMPL_var, TMPL_if, TMPL_unless, TMPL_elsif, and TMPL_foreach. For example:

<TMPL_var SPRINTF(GETTEXT("%d minutes ago", min), min)>

<TMPL_var DEFAULT(HTMLESCAPE(url), "http://ctpp.havoc.ru")>

<TMPL_if (GET_TYPE(var) == "STRING")>
    <TMPL_var GETTEXT("var is string")>
</TMPL_if>

<TMPL_foreach LIST("eeny", "meeny", "miny", "moe") as item>
    <TMPL_var item>
</TMPL_foreach>

Blocks

A block is reusable piece of a template called by name.

Example of usage:

<TMPL_block "simple-block">
    Some text
</TMPL_block>

The TMPL_call tag is used for calling a block:

<TMPL_call "simple-block">
<TMPL_call some_var>

A block can have arguments:

<TMPL_block 'some-block' args(a, b, c)>
    <TMPL_var a>, <TMPL_var b>, and <TMPL_var c>
</TMPL_block>

<TMPL_call 'some-block' args(foo, bar, baz)>

Definition blocks inside another blocks is forbidden.

Library reference

AVG (flag, a[, b, ...])

Return average of a[, b, ...], according to chosen algorithm by flag. The values of flag are 'a' for arithmetic mean, 'g' for geometric mean, 'h' for harmonic mean, and 'q' for quadratic mean.

Examples:

AVG('a', 1, 2, 3) -> 2
AVG('g', 1, 2, 3) -> 1.81712059283
AVG('h', 1, 2, 3) -> 1.63636363636
AVG('q', 1, 2, 3) -> 2.16024689947

BASE64_DECODE (x)

Decode the Base64 encoded string x.

BASE64_ENCODE (x)

Encode the string x use Base64.

CAST (flag, x)

Convert the type of x to a type specified by flag. The values of flag are "i[nteger]", "o[ctal]", "h[exadecimal]", "f[loat]", and "s[tring]".

For x starts with 0x or 0X, "integer" flag behaves as "hexadecimal" flag. For x starts with 0, "integer" flag behaves as "octal" flag.

Examples:

CAST("int", 1.345) -> 1
CAST("dec", "010") -> 10
CAST("hex", "010") -> 16

CONCAT (a[, b, ...])

Return a string which is the concatenation of the values a[, b, ...].

Example:

CONCAT('a', 1, 2, 3) -> a123

CONTEXT ()

Return a mapping of the rendered context.

DATE_FORMAT (x, format)

Formats x according to the format specification format (see 'man 3 strftime'). The argument x is the number of seconds elapsed since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).

Example:

DATE_FORMAT(1200490323, "%Y-%m-%d %H:%M:%S") -> 2008-01-16 16:32:03

DEFAULT (x, y)

If x is nonzero return x else return y.

Examples:

DEFAULT("", "default_string")   -> default_string
DEFAULT(nonexistent, "default") -> default
DEFAULT(0, 1)                   -> 1

DEFINED (a[, b, ...])

If all of a[, b, ...] exist return 1 else return 0.

ERROR ()

Create runtime error.

FORM_PARAM (x, y)

With name x and value y, output a hidden field of HTML form.

It is equivalent to the next:

<TMPL_verbose>
<TMPL_if y>
    <input type="hidden" name="x" value="<TMPL_var URLESCAPE(y)>">
</TMPL_if>
</TMPL_verbose>

GETTEXT (msgid[, msgid_plural, n][, domain])

Translate a text string msgid into the user's native language, by looking up the translation in a message catalog.

If a translation was found, the message is converted to the locale's codeset and returned. Otherwise msgid or msgid_plural is returned.

The appropriate plural form depends on the number n and the language of the message catalog where the translation was found.

The argument domain is a set of translatable messages.

The function _() is alias of GETTEXT().

Examples:

GETTEXT("Hello, World!")                                -> Привет, Мир!
_("Hello, World!")                                      -> Привет, Мир!
_("Hello, World!", "mydomain")                          -> Привет, Другой Мир!
SPRINTF(_("%d hour", "%d hours", 1), 1)                 -> 1 час
SPRINTF(_("%d minute", "%d minutes", 2, "mydomain"), 2) -> 2 минуты

GET_TYPE (x)

Return a printable type of x. The types are "*UNDEF*" for undefined variables, "STRING" for strings, "INTEGER" for integers, "REAL" for floating-point numbers, "HASH" for mappings, and "ARRAY" for arrays.

HASH_KEYS (x)

Return an array of x's keys. The argument x should be mapping.

HMAC_MD5 (x, key)

Compute a hash value for the specified x using the supplied key.

HOSTNAME ()

Return the hostname of the current processor.

HREF_PARAM (x, y)

With name x and value y, output parameters of HTML links.

It is equivalent to the next:

<TMPL_if a>x=<TMPL_var URLESCAPE(y)></TMPL_if>

HTMLESCAPE (a[, b, ...])

Escape &, <, ', ", and > in the strings of data a[, b, ...].

HTMLESCAPE() returns result of concatenation of the strings a[, b, ...].

ICONV (x, src, dst[, flags])

Convert the string x from the coded character set src to dst.

The argument flags are 'i' or 'I' for discarding illegal sequence, and 't' or 'T' for enabling transliteration in the conversion. The argument flags works in FreeBSD only.

See 'iconv -l` for list which contains all the coded character sets known.

IN_ARRAY (x, array)

Return 1 if x was found in array, else return 0.

IN_SET (x, a[, b, ...])

Return 1 if x was found in a[, b, ...], else return 0.

JSONESCAPE (a[, b, ...])

Escape ", \, /, \b, \f, \n, \r, \t, ', \v, and \0 in the strings of data a[, b, ...]. If character's value is smaller than \u0032, it is encoded with \uXXXX format for hex digits XXXX.

JSONESCAPE() returns result of concatenation of the strings a[, b, ...].

JSON (x)

Serialize x to the JavaScript Object Notation (JSON).

LIST_ELEMENT (a[, b, ...], x)

Return an element from a[, b, ...] by the index x.

LIST ([a, b, ...])

Return an array of [a, b, ...]. It can be empty.

LOG (x[, base])

With one argument, return the natural logarithm of x (to base e).

With two arguments, return the logarithm of x to the given base, calculated as LOG(x) / LOG(base).

MAX (a[, b, ...])

Return the largest item of a[, b, ...].

MB_SIZE (x)

MB_ prefix marks function, which works with multibyte strings.

See SIZE.

MB_SUBSTR (x, offset[, bytes[, y]]])

MB_ prefix marks function, which works with multibyte strings.

See SUBSTR.

MB_TRUNCATE (x, offest[, addon])

MB_ prefix marks function, which works with multibyte strings.

See TRUNCATE.

MD5 (a[, b, ...])

Return the MD5 hash of a[, b, ...].

MIN (a[, b, ...])

Return the smallest item of a[, b, ...].

NUM_FORMAT (x, y)

Return the formatted integer x with period y.

Example:

NUM_FORMAT(1234567, ",") -> 1,234,567

OBJ_DUMP ([a, b, ...])

Return dump of the arguments [a, b, ...]. Return dump of all variables if no arguments.

RANDOM ([[min,] max])

Return a random number in the range (min, max]. The range (min, max] equals to 0 .. RAND_MAX, if no arguments.

SIZE (x)

Return the number of items of a sequence x.

SPRINTF (format, a[, b, ...])

Produce output according to a format. After the argument format, it expects at least as many additional arguments as specified in format.

The argument format can optionaly contain embedded format tags that are substituted by the values specified in a[, b, ...].

See 'man 3 printf' for more information.

SUBSTR (x, offset[, bytes[, y]]])

Return the characters in the string x starting at a specified position offset and continuing for a specified number of characters bytes. If the argument y exists, then return the string x with replaced the characters with y.

TRUNCATE (x, offest[, addon])

Return the string x, if it is less than or equal to offset characters long. If it is longer, it truncates the string.

Return the string with addon, if the argument addon exists.

URIESCAPE (a[, b, ...])

Convert characters of the strings a[, b, ...] into their corresponding escape sequences.

URIESCAPE() returns result of concatenation of the strings a[, b, ...].

URLESCAPE (a[, b, ...])

Convert characters of the strings a[, b, ...] into their corresponding escape sequences. It replaces spaces with "+" instead of "%20".

URLESCAPE() returns result of concatenation of the strings a[, b, ...].

VERSION ([x])

Return the current version of CT++.

Return extended information if x equals to "full".

WMLESCAPE (a[, b, ...])

Replace < with &gt;, > with &lt;, " with &quot;, ' with &apos;, $ with $$, and & with &amp; in the strings of data a[, b, ...].

WMLESCAPE() returns result of concatenation of the strings a[, b, ...].

XMLESCAPE (a[, b, ...])

Replace < with &gt;, > with &lt;, " with &quot;, ' with &apos;, and & with &amp; in the strings of data a[, b, ...].

XMLESCAPE() returns result of concatenation of the strings a[, b, ...].