NAME
Text::Template::Simple - Simple text template engine
SYNOPSIS
use Text::Template::Simple;
my $tts = Text::Template::Simple->new();
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 %>
DESCRIPTION
This document describes version 0.62_13
of Text::Template::Simple
released on 10 April 2009
.
WARNING: This version of the module is part of a developer (beta) release of the distribution and it is not suitable for production use.
This is a simple template module. There is no extra template/mini language. Instead, it uses Perl as a template language. Templates can be cached on disk or inside the memory via internal cache manager. It is also possible to use static/dynamic includes, pass parameters to includes and allpt filters on them.
SYNTAX
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:
<?perl
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:
<%#
This
whole
block
will
be
ignored
%>
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 kind of includes, so the following is valid code:
<%+ "/path/to/" . $txt %>
<%* "/path/to/" . $myfile %>
Chomping
Chomping is the removal of whitespace before and after your directives. This can be useful if you're generating plain text (instead of HTML which'll ignore spaces most of the time). You can either remove all space or replace multiple whitespace with a single space (collapse). Chomping can be enabled per directive or globally via options to the constructor. See "pre_chomp" and "post_chomp" options to "new" 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:
Chomp:
raw content
<%- my $foo = 42; -%>
raw content
<%=- $foo -%>
raw content
<%*- /mt/dynamic.tts -%>
raw content
Collapse:
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:
Foo
<%- $prehistoric = $] < 5.008 -%>
Bar
Will become:
FooBar
And this one:
Foo
<%~ $prehistoric = $] < 5.008 -%>
Bar
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" option for "new" 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
Include commands are separated by pipes in an include directive. Currently supported parameters are: PARAM:
, FILTER:
.
<%+ /path/to/static.tts | FILTER: MyFilter | PARAM: test => 123 %>
<%* /path/to/dynamic.tts | FILTER: MyFilter | PARAM: test => 123 %>
FILTER:
defines the list of filters to apply to the output of the include. PARAM:
defines the parameter list to pass to the included file.
INCLUDE FILTERS
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 %>
IMPLEMENTING INCLUDE FILTERS
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
return;
}
INCLUDE PARAMETERS
Just pass the parameters as describe above and fetch them via @_
inside the included file.
BLOCKS
A block consists of a header part and the content.
<%| HEADER;
BODY
%>
HEADER
includes the commands and terminated with a semicolon. BODY
is the actual block content.
BLOCK FILTERS
Identical to include filters, but works on blocks of text:
<%| FILTER: HTML, OtherFilter;
<p>&FooBar=42</p>
%>
METHODS
new
Creates a new template object and can take several parameters.
delimiters
Must be an array ref containing the two delimiter values: the opening delimiter and the closing delimiter:
$tts = Text::Template::Simple->new(
delimiters => ['<?perl', '?>'],
);
Default values are <%
and %>
.
cache
Pass this with a true value if you want the cache feature. In-memory cache will be used unless you also pass a "cache_dir" parameter.
cache_dir
If you want disk-based cache, set this parameter to a valid directory path. You must also set "cache" to a true value.
resume
If has a true value, the die()
able code fragments will not terminate the compilation of remaining parts, the compiler will simply resume it's job. However, enabling this may result with a performance penalty if cache is not enabled. If cache is enabled, the performance penalty will show itself after every compilation process (upto 2x
slower).
This option is currently experimental and uses more resources. Only enable it for debugging.
CAVEAT: <% use MODULE %>
directives won't resume.
strict
If has a true value, the template will be compiled under strict. Enabled by default.
safe
Set this to a true value if you want to execute the template code in a safe compartment. Disabled by default and highly experimental. This option can also disable some template features.
If you want to enable some unsafe conditions, you have to define Text::Template::Simple::Compiler::Safe::permit
sub in your controller code and return a list of permitted opcodes inside that sub:
sub Text::Template::Simple::Compiler::Safe::permit {
my $class = shift;
return qw(:default :subprocess); # enable backticks and system
}
If this is not enough for you, you can define the safe compartment all by yourself by defining Text::Template::Simple::Compiler::Safe::object
:
sub Text::Template::Simple::Compiler::Safe::object {
require Safe;
my $safe = Safe->new('Text::Template::Simple::Dummy');
$safe->permit(':browse');
return $safe;
}
:default
, require
and caller
are enabled opcodes, unless you define your own. You have to disable strict
option to disable require
opcode. Disabling caller
will also make your require
/use
calls die in perl 5.9.5 and later.
See Safe and especially Opcode for opcode lists and other details.
header
This is a string containing global elements (global to this particular object) for templates. You can define some generally accessible variables with this:
$tts = Text::Template::Simple->new(
header => q~ my $foo = "bar"; ~,
);
and then you can use it (without defining) inside any template that is compiled with $tts
object:
Foo is <%=$foo%>
add_args
ARRAYref. Can be used to add a global parameter list to the templates.
$tts = Text::Template::Simple->new(
add_args => [qw(foo bar baz)],
);
and then you can fetch them inside any template that is compiled with $tts
object:
<%
my $foo = shift;
my $bar = shift;
my $baz = shift;
%>
Foo is <%=$foo%>. Bar is <%=$bar%>. Baz is <%=$baz%>
But it'll be logical to combine it with header
parameter:
$tts = Text::Template::Simple->new(
header => q~my $foo = shift;my $bar = shift;my $baz = shift;~,
add_args => [qw(foo bar baz)],
);
and then you can use it inside any template that is compiled with $tts
object without manually fetching all the time:
Foo is <%=$foo%>. Bar is <%=$bar%>. Baz is <%=$baz%>
Can be useful, if you want to define a default object:
$tts = Text::Template::Simple->new(
header => q~my $self = shift;~,
add_args => [$my_default_object],
);
and then you can use it inside any template that is compiled with $tts
object without manually fetching:
Foo is <%= $self->{foo} %>. Test: <%= $self->method('test') %>
warn_ids
If enabled, the module will warn you about compile steps using template ids. You must both enable this and the cache. If cache is disabled, no warnings will be generated.
iolayer
This option does not have any effect under perls older than 5.8.0
. Set this to utf8
(no initial colon) if your I/O is UTF-8
. Not tested with other encodings.
stack
This option enables caller stack tracing for templates. The generated list is sent to warn
. So, it is possible to capture this data with a signal handler. See Text::Template::Simple::Caller for available options.
It is also possible to send the output to the template output buffer, if you append :buffer
to the type of the stack
option:
$tts = Text::Template::Simple->new(
stack => 'string:buffer',
);
html_comment
is the same as string
except that it also includes HTML comment markers. text_table
needs the optional module Text::Table
.
This option is also available to all templates as a function named stack
for individual stack dumping. See Text::Template::Simple::Dummy for more information.
monolith
Controls the behavior when using includes. If this is enabled, the template and all it's includes will be compiled into a single document. If monolith
is disabled, then the includes will be compiled individually into separate documents.
If you need to pass the main template variables (my
vars) into dynamic includes, then you need to enable this option. However, if you are using the cache, then the included templates will not be updated automatically.
monolith
is disabled by default.
include_paths
An ARRAY reference. If you want to use relative file paths when compiling/including template files, add the paths of the templates with this parameter.
pre_chomp
use Text::Template::Simple::Constants qw( :chomp );
$pre = CHOMP_NONE; # no chomp
$pre = CHOMP_ALL; # remove all whitespace
$pre = COLLAPSE_ALL; # replace all ws with a single space
$tts = Text::Template::Simple->new(
pre_chomp => $pre,
);
post_chomp
use Text::Template::Simple::Constants qw( :chomp );
$post = CHOMP_NONE; # no chomp
$post = CHOMP_ALL; # remove all whitespace
$post = COLLAPSE_ALL; # replace all ws with a single space
$tts = Text::Template::Simple->new(
post_chomp => $post,
);
compile DATA [, FILL_IN_PARAM, OPTIONS]
Compiles the template you have passed and manages template cache, if you've enabled cache feature. Then it returns the compiled template. Accepts three different types of data as the first parameter; a reference to a filehandle (GLOB
), a string or a file path (path to the template file).
First parameter (DATA)
The first parameter can take four different values; a filehandle, a string, a file path or explicit type definition via an ARRAY reference. Distinguishing filehandles are easy, since they'll be passed as a reference (but see the bareword issue below). So, the only problem is distinguishing strings and file paths. compile
first checks if the string length is equal or less than 255 characters and then tests if a file with this name exists. If all these tests fail, the string will be treated as the template text.
File paths
You can pass a file path as the first parameter:
$text = $tts->compile('/my/templates/test.tts');
Strings
You can pass a string as the first parameter:
$text = $tts->compile(q~
<%for my $i (0..10) {%>
counting <%=$i%>...
<%}%>
~);
Filehandles
GLOB
s must be passed as a reference. If you are using bareword filehandles, be sure to pass it's reference or it'll be treated as a file path and your code will probably die
:
open MYHANDLE, '/path/to/foo.tts' or die "Error: $!";
$text = $tts->compile(\*MYHANDLE); # RIGHT.
$text = $tts->compile( *MYHANDLE); # WRONG. Recognized as a file path
$text = $tts->compile( MYHANDLE); # WRONG. Ditto. Dies under strict
or use the standard IO::File
module:
use IO::File;
my $fh = IO::File->new;
$fh->open('/path/to/foo.tts', 'r') or die "Error: $!";
$text = $tts->compile($fh);
or you can use lexicals inside open
if you don't care about compatibility with older perl:
open my $fh, '/path/to/foo.tts' or die "Error: $!";
$text = $tts->compile($fh);
Filehandles will not be closed.
Explicit Types
Pass an arrayref containing the type and the parameter to disable guessing and forcing the type:
$text = $tts->compile( [ FILE => '/path/to/my.tts'] );
$text = $tts->compile( [ GLOB => \*MYHANDLE] );
$text = $tts->compile( [ STRING => 'I am running under <%= $] %>'] );
Type can be one of these: FILE
, GLOB
, STRING
.
FILL_IN_PARAM
An arrayref. Everything inside this will be accessible from the usual @_
array inside templates.
OPTIONS
A hashref. Several template specific options can be set with this parameter.
id
Controls the cache id generation. Can be useful, if you want to pass your own template id. If false or set to AUTO
, internal mechanisms will be used to generate template keys.
map_keys
This will change the compiler behavior. If you enable this, you can construct templates like this:
This is "<%foo%>", that is "<%bar%>" and the other is "<%baz%>"
i.e.: only the key names can be used instead of perl constructs. and as you can see, "<%
" is used instead of "<%=
". map_keys
also disables usage of perl constructs. Only bare words can be used and you don't have to fetch parameters via @_
inside the template. Here is an example:
$text = $tts->compile(
q~This is "<%foo%>", that is "<%bar%>"
and the other is "<%baz%>"~,
[
foo => "blah 1",
bar => "blah 2",
baz => "blah 3",
],
{
map_keys => 1
},
);
Can be good (and simple) for compiling i18n texts. If you don't use map_keys
, the above code must be written as:
$text = $tts->compile(
q~<%my(%l) = @_%>This is "<%=$l{foo}%>", that is "<%=$l{bar}%>"
and the other is "<%=$l{baz}%>"~,
[
foo => "blah 1",
bar => "blah 2",
baz => "blah 3",
],
);
If map_keys
is set to 'init', then the uninitialized values will be initialized to an empty string. But beware; init
may cloak template errors. It'll silence uninitialized warnings, but can also make it harder to detect template errors.
If map_keys
is set to 'check', then the compiler will check for the key's existence and check if it is defined or not.
chkmt
If you are using file templates (i.e.: not FH or not string) and you set this to a true value, modification time of templates will be checked and compared for template change.
cache
Returns the Text::Template::Simple::Cache object.
io
Returns the Text::Template::Simple::IO object.
connector
Returns the class name of the supplied connector.
CLASS METHODS
These are all global (i.e.: not local to any particular object).
DEBUG
Used to enable/disable debugging. Debug information is generated as warnings:
Text::Template::Simple->DEBUG(1); # enable
Text::Template::Simple->DEBUG(0); # disable
Text::Template::Simple->DEBUG(2); # more verbose
DEBUG
is disabled by default.
DIGEST
Returns the digester object:
$digester = Text::Template::Simple->DIGEST;
print $digester->add($data)->hexdigest;
CACHE MANAGER
Cache manager has two working modes. It can use disk files or memory for the storage. Memory based cache is far more faster than disk cache.
The template text is first parsed and compiled into an anonymous perl sub source. Then an unique key is generated from your source data (you can by-pass key generation phase if you supply your own id parameter).
If in-memory cache is used, the perl source will be compiled into an anonymous sub inside the in-memory cache hash and this compiled version will be used instead of continiously parsing/compiling the same template.
If disk cache is used, a template file with the ".tts.cache
" extension will be generated on the disk.
Using cache is recommended under persistent environments like mod_perl
and PerlEx
.
In-memory cache can use two or three times more space than disk-cache, but it is far more faster than disk cache. Disk cache can also be slower than no-cache for small templates, since there is a little overhead when generating unique keys with the "DIGESTER" and also there will be a disk I/O. There is a modification time check option for disk based templates (see compile).
DIGESTER
Cache keys are generated with one of these modules:
Digest::SHA
Digest::SHA1
Digest::SHA2
Digest::SHA::PurePerl
Digest::MD5
MD5
Digest::Perl::MD5
SHA algorithm seems to be more reliable for key generation, but md5 is widely available and Digest::MD5
is in CORE.
FUNCTIONS
tts [ NEW_ARGS, ] COMPILE_ARGS
This function is a wrapper around the Text::Template::Simple object. It creates it's own temporary object behind the scenes and can be used for quick Perl one-liners for example. Using this function other than testing is not recommended.
NEW_ARGS
is optional and must be a hashref containing the parameters to "new". COMPILE_ARGS
is a list and everything it contains will be passed to the "compile" method.
It is possible to import this function to your namespace:
use Text::Template::Simple qw( tts );
print tts("<%= scalar localtime time %>");
print tts( { strict => 1 }, "<%= scalar localtime time %>");
EXAMPLES
TODO
ERROR HANDLING
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.
BUGS
Contact the author if you find any bugs.
CAVEATS
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.
Speed
There is an initialization cost and this'll 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'll 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:
Devel::Size
Text::Table
Perl::Tidy
SEE ALSO
Apache::SimpleTemplate, Text::Template, Text::ScriptTemplate, Safe, Opcode.
MONOLITHIC VERSION
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.
AUTHOR
Burak Gürsoy, <burak@cpan.org>
COPYRIGHT
Copyright 2004-2008 Burak Gürsoy. All rights reserved.
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.