Burak Gürsoy


Text::Template::Simple - Simple text template engine


   use Text::Template::Simple;
   my $tts = Text::Template::Simple->new();
   print $tts->compile( $FILEHANDLE );
   print $tts->compile('Hello, your perl is at <%= $^X %>');
   print $tts->compile(
            'hello.tts', # the template file
            [ name => 'Burak', location => 'Istanbul' ]

Where hello.tts has this content:

   <% my %p = @_; %>
   Hello <%= $p{name} %>,
   I hope it's sunny in <%= $p{location} %>.
   Local time is <%= scalar localtime time %>


This document describes version 0.90 of Text::Template::Simple released on 5 July 2016.

This is a simple template module. There is no extra template/mini language. Instead, it uses Perl as the template language. Templates can be cached on disk or inside the memory via the internal cache manager. It is also possible to use static/dynamic includes, pass parameters to includes and apply filters on them. Also see Text::Template::Simple::API for the full API reference.


Template syntax is very simple. There are few kinds of delimiters:

  • <% %> Code Blocks

  • <%= %> Self-printing Blocks

  • <%! %> Escaped Delimiters

  • <%+ %> Static Include Directives

  • <%* %> Dynamic include directives

  • <%# %> Comment Directives

  • <%| %> Blocks with commands

A simple example:

   <% foreach my $x (@foo) { %>
      Element is <%= $x %>
   <% } %>

Do not directly use print() statements, since they'll break the template compilation. Use the self printing <%= %> blocks.

It is also possible to alter the delimiters:

   $tts = Text::Template::Simple->new(
      delimiters => [qw/<?perl ?>/],

then you can use them inside templates:

      my @foo = qw(bar baz);
      foreach my $x (@foo) {
   Element is <?perl= $x ?>
   <?perl } ?>

If you need to remove a code temporarily without deleting, or need to add comments:


If you put a space before the pound sign, the block will be a code block:

      # this is normal code not a comment directive
      my $foo = 42;

If you want to include a text or HTML file, you can use the static include directive:

   <%+ my_other.html %>
   <%+ my_other.txt  %>

Included files won't be parsed and included statically. To enable parsing for the included files, use the dynamic includes:

   <%* my_other.html %>
   <%* my_other.txt  %>

Interpolation is also supported with both kinds of includes, so the following is valid code:

   <%+ "/path/to/" . $txt    %>
   <%* "/path/to/" . $myfile %>


Chomping is the removal of white space before and after your directives. This can be useful if you're generating plain text (instead of HTML which will ignore spaces most of the time). You can either remove all space or replace multiple white space with a single space (collapse). Chomping can be enabled per directive or globally via options to the constructor. See "pre_chomp" in Text::Template::Simple::API and "post_chomp" in Text::Template::Simple::API options to "new" in Text::Template::Simple::API to globally enable chomping.

Chomping is enabled with second level commands for all directives. Here is a list of commands:

   -   Chomp
   ~   Collapse
   ^   No chomp (override global)

All directives can be chomped. Here are some examples:


   raw content
   <%- my $foo = 42; -%>
   raw content
   <%=- $foo -%>
   raw content
   <%*- /mt/dynamic.tts  -%>
   raw content


   raw content
   <%~ my $foo = 42; ~%>
   raw content
   <%=~ $foo ~%>
   raw content
   <%*~ /mt/dynamic.tts  ~%>
   raw content

No chomp:

   raw content
   <%^ my $foo = 42; ^%>
   raw content
   <%=^ $foo ^%>
   raw content
   <%*^ /mt/dynamic.tts  ^%>
   raw content

It is also possible to mix the chomping types:

   raw content
   <%- my $foo = 42; ^%>
   raw content
   <%=^ $foo ~%>
   raw content
   <%*^ /mt/dynamic.tts  -%>
   raw content

For example this template:

   <%- $prehistoric = $] < 5.008 -%>

Will become:


And this one:

   <%~ $prehistoric = $] < 5.008 -%>

Will become:

   Foo Bar

Chomping is inspired by Template Toolkit (mostly the same functionality, although TT seems to miss collapse/no-chomp per directive option).

Accessing Template Names

You can use $0 to get the template path/name inside the template:

   I am <%= $0 %>

Escaping Delimiters

If you have to build templates like this:

   Test: <%abc>

or this:

   Test: <%abc%>

This will result with a template compilation error. You have to use the delimiter escape command !:

   Test: <%!abc>
   Test: <%!abc%>

Those will be compiled as:

   Test: <%abc>
   Test: <%abc%>

Alternatively, you can change the default delimiters to solve this issue. See the "delimiters" in Text::Template::Simple::API option for "new" in Text::Template::Simple::API for more information on how to do this.

Template Parameters

You can fetch parameters (passed to compile) in the usual perl way:

      my $foo = shift;
      my %bar = @_;
   Baz is <%= $bar{baz} %>


Include commands are separated by pipes in an include directive. Currently supported parameters are:

   <%+ /path/to/static.tts  | FILTER: MyFilter %>
   <%* /path/to/dynamic.tts | FILTER: MyFilter | PARAM: test => 123 %>

PARAM defines the parameter list to pass to the included file. FILTER defines the list of filters to apply to the output of the include. SHARE used to list the variables to share with the included template when the monolith option is disabled.


Use the include command FILTER: (notice the colon in the command):

   <%+ /path/to/static.tts  | FILTER: First, Second        %>
   <%* /path/to/dynamic.tts | FILTER: Third, Fourth, Fifth %>


Define the filter inside Text::Template::Simple::Dummy with a filter_ prefix:

   package Text::Template::Simple::Dummy;
   sub filter_MyFilter {
      # $tts is the current Text::Template::Simple object
      # $output_ref is the scalar reference to the output of
      #    the template.
      my($tts, $output_ref) = @_;
      $$output_ref .= "FILTER APPLIED"; # add to output


Just pass the parameters as described above and fetch them via @_ inside the included file.


Text::Template::Simple compiles every template individually with separate scopes. A variable defined in the master template is not accessible from a dynamic include. The exception to this rule is the monolith option to new. If it is enabled; the master template and any includes it has will be compiled into a single document, thus making every variable defined at the top available to the includes below. But this method has several drawbacks, it disables cache check for the sub files (includes) --you'll need to edit the master template to force a cache reload-- and it can not be used with interpolated includes. If you use an interpolated include with monolith enabled, you'll get an error.

If you don't use monolith (disabled by default), then you'll need to share the variables somehow to don't repeat yourself. Variable sharing is demonstrated in the below template:

      my $foo = 42;
      my $bar = 23;
   <%* dyna.inc | SHARE: $foo, $bar %>

And then you can access $foo and $bar inside dyna.inc. There is one drawback by shared variables: only SCALARs can be shared. You can not share anything else. If you want to share an array, use an array reference instead:

      my @foo = (1..10);
      my $fooref = \@foo;
   <%* dyna.inc | SHARE: $fooref %>


A block consists of a header part and the content.

   <%| HEADER;

HEADER includes the commands and terminated with a semicolon. BODY is the actual block content.


WARNING Block filters are considered to be experimental. They may be changed or completely removed in the future.

Identical to include filters, but works on blocks of text:

   <%| FILTER: HTML, OtherFilter;

Note that you can not use any variables in these blocks. They are static.









See Text::Template::Simple::API for the technical/gory details.




You may need to eval your code blocks to trap exceptions. Some recoverable failures are silently ignored, but you can display them as warnings if you enable debugging.


Contact the author if you find any bugs.


No mini language

There is no mini-language. Only perl is used as the template language. So, this may or may not be safe from your point of view. If this is a problem for you, just don't use this module. There are plenty of template modules with mini-languages inside CPAN.


There is an initialization cost and this will show itself after the first compilation process. The second and any following compilations will be much faster. Using cache can also improve speed, since this will eliminate the parsing phase. Also, using memory cache will make the program run more faster under persistent environments. But the overall speed really depends on your environment.

Internal cache manager generates ids for all templates. If you supply your own id parameter, this will improve performance.

Optional Dependencies

Some methods/functionality of the module needs these optional modules:



Text::Template::Simple::API, Apache::SimpleTemplate, Text::Template, Text::ScriptTemplate, Safe, Opcode.


Text::Template::Simple consists of 15+ separate modules. If you are after a single .pm file to ease deployment, download the distribution from a CPAN mirror near you to get a monolithic Text::Template::Simple. It is automatically generated from the separate modules and distributed in the monolithic_version directory.

However, be aware that the monolithic version is not supported.


Burak Gursoy <burak@cpan.org>.


Copyright 2004 - 2016 Burak Gursoy. All rights reserved.


This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.24.0 or, at your option, any later version of Perl 5 you may have available.