Text::TemplateLite - Pure-Perl text templates with bare-bones syntax, compact size, and limitable resource usage


Version 0.01


    use Text::TemplateLite;

    my $tpl = Text::TemplateLite->new;

    $tpl->set('Hello, <<$who>>');
    print $tpl->render({ who => 'world' })->result;
    # Generates "Hello, world"

    my $rdr = $tpl->new_renderer;
    print $rdr->render({ who => 'universe' })->result;
    # Generates "Hello, universe" with a configurable and
    # reusable renderer (see Text::TemplateLite::Renderer)



Text::TemplateLite is intended primarily for "string-sized" templating (e.g. for message localization rather than entire "pages") using compact (terse?) templates with a (relatively) simple syntax.

It is anticipated that templates may (at least sometimes) be entered or managed by users whose skill set does not include "Perl programmer" (perhaps a web site administrator, translator, or non-Perl programmer).

Basic length and execution limits provide a measure of protection against accidental or malicious time- and/or space-based resource attacks. These are managed by the rendering companion class, Text::TemplateLite::Renderer.

By design, only basic functionality is included in this module. Use parts or all of the Text::TemplateLite::Standard function library and/or create your own custom library to extend its capabilities.


A template consists of literal text and template code. Any text between "<<" and ">>" that does not contain "<<" or ">>" is treated as template code. Everything else is literal text.

Template code can contain sequences in any combination of the following:


Anything from "/*" to the closest "*/" is ignored and does not count as a step (see "Steps").

String Literals

To include literal text within code text, surround the text with single quotes (') or double quotes ("). You can "escape" either kind of quote or < or > in either kind of string by preceding it with a backslash (\', \", \<, or \>). Use '<\<' or '>\>' to generate "<<" or ">>" within code text.

No variable substitution is performed within either kind of string literal.

Numeric Literals

Numeric literals consist of an optional minus sign and one or more digits, optionally followed by a decimal point and additional digits.

Variable Substitutions

A dollar sign ($) followed by a name consisting of one or more letters, digits, underscores (_), and/or non-initial periods (.) will be replaced by the corresponding value from the variables supplied either at rendering time or set during template execution.

Variables can also store nested templates. Substituting a variable containing a nested template executes the nested template. These templates can be passed parameters using the same syntax as function calls. The parameters will appear in the nested template as template variables "$1", "$2", etc. Parameter "$0" will contain the number of parameters.

Parameters after a non-template variable are ignored, unevaluated.

    $foo /* variable or nested template without parameters */
    "$foo is " $foo /* only the second $foo is substituted */
    $foo('hey', 'there') /* nested template(?) with parameters */

See "TEMPLATE FUNCTIONS" in Text::TemplateLite::Standard for information on creating nested templates.

In future releases, periods in variable names may have structural meaning (e.g. to support lists or maps). Do not write templates that expect "$a" to be unrelated to "$a.b" or "$a.5", for example. For now, however, periods are just part of the name.

Function And External Template Calls

Any other combination of alpha-numeric characters, or combination of symbols other than parentheses or comma, are treated as the name of a function or external template call. Either may optionally be passed a list of zero or more parameters, surrounded by parentheses and separated by commas.

Parameters to external templates should be provided in "name, value" pairs.

    cr nl /* call "cr" and "nl" without parameters */
    foo('hey', 'there') /* pass foo two strings (or hey=there) */

See "TEMPLATE FUNCTIONS" in Text::TemplateLite::Standard for some related functions.

Calls to unregistered names will instead call a definition with a zero-length name, if registered, or "undef_call($name, $args, $renderer)" otherwise.


Each element (literal, substitution, call, etc.) evaluated during template execution is counted as a "step". For example:

    $=('a', 2)     /*  3 steps: $=, 'a', and 2 */
    ??(=($a, 1),   /* +4 steps: ??, =, $a, and 1 */
      '$a is 1',   /*  1 step not eval'd/counted (= was false) */
      =($a, 2),    /* +3 steps: =, $a, 2 */
      '$a is 2',   /* +1 step: '$a is 2' */
      'other')     /*  1 step not eval'd/counted (not reached) */
    /* renders '$a is 2' in 11 steps */

    ?*(<($a, 4), 'loop' $=('a', +($a, 1)))
    /* 1 step: ?*
      +3 steps: <, $a, 4 (assuming $a is 2 from above)
      +6 steps: 'loop', $=, 'a', +, $a, 1 ($a becomes 3)
      +3 steps: <, $a, 4
      +6 steps: 'loop', $=, 'a', +, $a, 1 ($a becomes 4)
      +3 steps: <, $a, 4 (now false, so loop stops)
      renders 'looploop' in 22 steps */


This section describes methods for normal usage.

new( )

This returns a new Text::TemplateLite template engine.

register($name, $definition)

Register a function (coderef definition) or an external template (Text::TemplateLite definition).

    $ttl->register('my_function', sub {
      my ($name, $args, $renderer) = @_;
      "You called function $name." });

    my $other_ttl = Text::TemplateLite->new();
    $other_ttl->set('You called an external template.');
    $ttl->register('external_tpl', $other_ttl);

If you register a definition with a zero-length name, it will be called in place of any call to an undefined function or external template instead of using the default undefined-call handler, "undef_call($name, $args, $renderer)".

Library functions (registered as coderefs) are passed three parameters:


This is the name of the function as it was invoked from the template.


This is an arrayref of code sequences for any parameters passed from the template. See "execute_sequence($code, $renderer)" and "execute_each($list, $renderer)".


This is the instance of Text::TemplateLite::Renderer that is managing rendering of the template.


Unregister a function or external template definition.


Set or change the template string (see "Syntax") and return the template object.

new_renderer( )

Returns a new renderer companion object assigned to this template engine. See Text::TemplateLite::Renderer.


Create a new renderer via "new_renderer( )", render the template, and return the renderer (not the result).


This section describes methods generally only used by library function authors.

execute_sequence($code, $renderer)

Execute the code step(s), if any, in the sequence $code using renderer $renderer.

A code sequence looks like:

    [ \@step1code, \@step2code, ... ]

This method is useful for "progressive" evaluation of individual parameters to functions. It is also used to execute the code resulting from each section of template code in a template.

Execution may stop or step results may be truncated in response to exceeded execution limits or a stop set in the rendering information.

A sequence consisting of a single function call can return multiple values if execute_sequence is called in array context. Otherwise, the concatenation of step values is returned.

execute_each($list, $renderer)

Execute an arrayref of code sequences and return a corresponding array of results. This is typically used by library functions to "bulk evaluate" their list of call parameters.

    $ttl->register('echo', sub {
        my ($name, $args, $renderer) = @_;

        "$name(" . join(', ', $renderer->execute_each($args))
          . ")";
    $ttl->set(q{<<echo('hello', 'world')>>});
    $ttl->render; # renders "echo(hello, world)"

    $ttl->register('uses2', sub {
        my ($name, $args, $renderer) = @_;

        join('', $renderer->template->execute_each(@{$args}[0, 1]));
    $ttl->render; # renders "justthese" using 3 steps (not 5)

execute_step($code, $renderer)

Execute one code step $code with renderer $renderer unless the total_steps limit has been reached, in which case the total_steps limit is marked exceeded.

_execute_step($code, $renderer)

This method does the "heavy lifting" after execute_step checks resource usage.

The step $code can be one of the following:

    [ "''" => $literal ]
    [ '$' => $var_name ]
    [ '()' => $fn_or_tpl [ \@a1codeseq, \@a2codeseq, ... ] ]

A variable substitution is executed as a nested template if it's value looks like this:

    [ '<>' => \@code_sequence ]


Execute the main template code with renderer $renderer and return the result.

You shouldn't need to use this method unless you're building or sub-classing a renderer.

execute_template($code, $args, $renderer)

This executes the code from a nested template after saving any previous numeric variables and then setting $0 and parameters $1 through $n.

Any previous numeric variables are restored before returning.

You shouldn't need this method except possibly if you're extending nested template functionality in some way.

undef_call($name, $args, $renderer)

This function is the default undefined-call handler called by the "_execute_step($code, $renderer)" method if no zero-length name is currently registered.

It increments the undef_calls count in the rendering information and returns no value.


These methods are used for parsing. If you extend these in a sub-class it's likely to get ugly pretty quickly.


Split template code text into tokens and return them as a list.

parse_list(\@tokens, \@stops)

Parse a block of code from the token list up to one of the stop symbols. This might be an entire code segment or parts of a call's parameter list. The code tree is returned.

parse_call($name, $tokens)

Parse a parameter list if one follows in the token stream and return the code tree for a call to the function or template in $name.


Un-escape backslashed characters for string literals.


Brian Katzung, <briank at>


Please report any bugs or feature requests to bug-text-templatelite at, or through the web interface at I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.


You can find documentation for this module with the perldoc command.

    perldoc Text::TemplateLite

You can also look for information at:


Text::TemplateLite::Renderer (the companion class to Text::TemplateLite for rendering management) and Text::TemplateLite::Standard (for standard library functions, with examples)

Mason ("powerful, high-performance templating for web and beyond")

Text::Template (an alternative template system based on embedding Perl code in templates)

Template::ToolKit (an alternative template system [based on "including the kitchen sink"]) for a comparison of template modules


Bricklayer::Templater, dTemplate, HTML::Macro, Mojo::Template, NTS::Template, Parse::Template, Ravenel, Solution, Template::Alloy, Template::Like, Template::Object, Template::Recall, Template::Replace, Template::Sandbox, Template::Tiny, Tenjin, Text::ClearSilver, Text::Clevery, Text::FillIn, Text::Macro, Text::Macros, Text::Merge, Text::MicroMason, Text::Printf, Text::ScriptTemplate, Text::SimpleTemplate, Text::TagTemplate, Text::Templar, Text::Template::Simple Text::Templet, Text::Tmpl, Text::Xslate

... and probably some I missed.


Copyright 2012 Brian Katzung.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.