Text::BasicTemplate -- Simple lexical text/html/etc template parser


 use Text::BasicTemplate;
 $bt = Text::BasicTemplate->new;
 my %dict = (
   name => 'John',
   location => sub { hostname() },
   condiments => [ 'Salt', 'Pepper', 'Catsup' ],
   sideeffects => { 'Salt' => 'causes high blood pressure',
                    'Pepper' => 'causes mariachi music',
                    'Catsup' => 'brings on warner bros. cartoons' },
   new => int rand 2

 $tmpl = "Hello, %name%; your mail is in %$MAIL%. Welcome to %location%!";
 print $bt->parse(\$tmpl,\%dict);

 $tmpl = "%if new%First time, %name%?%fi%".
         " Care for some %condiments%? ".
         " They are bad for you.  %sideeffects%."
 $bt->{hash_specifier}->{condiments} = ' ';
 print $bt->parse(\$tmpl,\%dict);


Text::BasicTemplate is a relatively straightforward template parsing module. Its overall function is to permit the separation of format-dependent output from code.

This module provides standard key/value substitutions, lexical evaluation/parsing, customizable formatting of perl datatypes, and assorted utility functions.

Templates may be structured by the use of arbitrarily nestable if-conditions (including elsif and else), and by the use of subroutine substitutions to provide list parsing. In general, the syntax for conditionals is that of perl itself.

Text::BasicTemplate attempts to be as fast and as secure as possible. It may be safely used upon tainted templates and with tainted substitutions without fear of execution of any malicious code.


If you have previously used Text::BasicTemplate v0.x, it is important to read the COMPATIBILITY section -- many things have changed, and compatibility is not guaranteed to be preserved in future versions.

In general, start with the SYNTAX section, and be sure to at least skim the new() section (for configuration settings) and parse() section (for an explanation of the dictionary).


One of the difficulties in employing a new template parser is picking up the apropriate syntax. Text::BasicTemplate does not spare you that, but it does adhere fairly closely to the syntax of perl itself with respect to operators, conditional operations, template subroutine calls, etc.

Anything to which Text::BasicTemplate should pay attention in a template is enclosed in percentage signs (%) -- any such segments will be interpreted as identifiers, operations, conditionals, or apropriate combinations thereof.

The simplest of these are variable substitutions; if parse() was passed a dictionary containing the pair (foo => "bar"), any instances of %foo% in the template will be evaluated as "bar." Other variable substitutions are available for lists and hashes, passed by reference in the parse() dictionary, as in (bar => \@r, snaf => \%h). In such a case %bar% will be evaluated to the contents of @r, and %snaf% to the contents of %h. Both will be formatted according to the configured delimiters (see LIST/HASH FORMATTING). Subroutine references may also be included in the dictionary; in their simple form, given ( subref => \&myfunction ), %subref% in the template will be evaluated to whatever is returned from &myfunction(). For more detail and features in subroutine handling, see SUBROUTINE SUBTITUTIONS.

In v0.9.7, BasicTemplate introduced simple conditional evaluation, providing one-level equality/inequality comparisons. In 2.0, after a total rewrite, the conditional evaluation was replaced with a lexically parsed scoping evaluation, providing arbitrarily deep nesting, most major unary and binary perl comparison operators, arbitrary combination of operations, nonconditional evaluation, etc. For the full explanation, read on:


Scoped evaluation is available to arbitrary depths, following the usual if/elsif/else pattern. if conditions are terminated by a fi. By example:

 # single if
 %if <condition>%

 # if-else
 %if <condition>%

 # if-elsif
 %if <condition>%
 %elsif <alternate condition>%

 # if-else-elsif
 %if <condition>%
 %elsif <alternate condition>%

A block above is some amount of further template contents, including none (%if <condition>%%fi% is perfectly valid, albeit not generally useful). A block may contain further conditions. Dictionary variables used in a conditional will only be evaluated if they come into scope -- for example, an elsif will not be evaluated unless its preceeding if or elsif evaluted false -- the principal consequence of this is that subroutines referenced in a conditional will be called only if they come into scope per the above.


Numeric literals may be given without alteration, e.g. %123%.

String literals should be given in double quotes, e.g. %"hello"%, or in single quotes, e.g. %'goodbye'%. Either sort may contain quotes of the other sort.

Scalar, list and hash variables should be given by name, e.g. %foo%.

%% gives a literal % sign and is considered normal text.

Environment variables may be used as %$PATH%.

Subroutine references should generally be referenced as %&foo%, or %&foo(arg1,arg2,...)% as apropriate. %foo% may be used for subroutines that return a scalar and will not require further parsing of their output -- see SUBROUTINE SUBSTITUTIONS.


Statements, conditional or otherwise, may be used outside of if/else contexts, and will have the results of the evaluation inserted at the point in which they occurred in the template. If used in an if/else statement, they will be evaluated, but the apropriate block will be output instead (pretty much the usual, IOW).

There is no operator precedence or conditional short-circuiting. %1 || 2% will evaluate both 1 and 2 (and return 2). Evaluation order is not guaranteed. For all matters requiring precedence, parentheses should be employed (e.g. %1 && (0 || 3)%).

Most of the perl unary and binary operators are supported; the trinary conditional is not. Operators presently provided are as follows:

eq ne lt le gt ge -- identical to their perl equivalents. Return 1 or false.

=~ !~ -- also equivalent to the perl versions, but must be enabled by setting enable_pattern_operator true (see new()), as a malformed pattern may kill the script -- so do not use them if you think you might be evaluating untrusted untrusted templates. The form for these is =~ pattern, not =~ /pattern/.

== != < <= > >= <=> -- perl equivalent

&& and || or -- the two ands and the two ors are considered equivalent, as there is no operator precedence in BasicTemplate. && and and return the value of the last operand.

. x -- perl equivalent; operand for x must be numeric.

+ - * / ** -- perl equivalent, divide-by-zero will be checked.

div mod -- equivalent to int(x/y) and x % y respectively.

^ & | << >> -- perl equivalent

! defined -- perl equivalent.

Examples: %foo + bar% -- evaluates to result of foo+bar, where foo and bar are variables given in the dictionary.

%if foo && (bar || snaf)% <block> %fi% -- evaluates foo, bar and snaf, outputs the block if the foo and one or more of bar and snaf were true.

%"your name: " . &yourname% -- outputs the string "your name: ", followed by whatever was returned by the subroutine referenced by the dictionary entry for yourname.

%if $MAIL =~ Maildir% Bernstein would be proud. %else% Eric Allman wants you for a sunbeam. %fi% -- evaluates according to whether the environment variable $MAIL contains the pattern 'Maildir.'

Note that blocks inside conditional statements begin immediately following the closing %, so in the above examples, the newline and spaces would be considered part of the block and output if the condition evaluated true. This is acceptable for most whitespace-independent usages, but you should not include whitespace in a conditional block if you do not want it in the output.


List references will be parsed and delimited according to $obj->{list_delimiter}->{listname} if supplied, and $obj->{list_delimiter}->{__default} if not (the latter is set with the default_list_delimiter argument to new()). The default is ", ".

Hash references will be delimited using $obj->{hash_delimiter}->{hashname} between pairs, and $obj->{hash_specifier}->{hashname} between key and value. As above, __default will be used if a delimiter has not been specified for the specific variable. The defaults are ", " and "=" respectively.


 $bt = Text::BasicTemplate->new(default_list_delimiter => ' and');

 $ss = "path: %path%" . "\n" . "env: %env%";
 $bt->{hash_specifier}->{env} = " is ";
 $bt->{hash_delimiter}->{env} = ", ";
 print $bt->parse(\$ss, { path => [ split(/:/,$ENV{PATH}) ],
                          env => \%ENV });

Output from the above would be of the form:

 /bin and /usr/bin and /usr/local/bin
 SHELL is bash, VISUAL is emacs, RSYNC_RSH is ssh


Subroutine references are something of a special-case in Text::BasicTemplate. In a simple form, they can be used thusly:

 sub heart_of_oak {
   return "me lads, 'tis to glory we steer";
 $bt = Text::BasicTemplate->new();
 $ss = "come cheer up %&rest_of_verse%";
 %ov = ( rest_of_verse => \&heart_of_oak );
 print $bt->parse(\$ss,\%ov);

This would output "come cheer up me lads, 'tis to glory we steer," by calling &heart_of_oak() and inserting its return value into the template.

You can pass literals and variables defined in the template to a subroutine, as follows:

 sub heart_of_oak {     
   my @lines = ( "come cheer up me lads",
                 "'tis to glory we steer",
                 "to find something new in this wonderful year" );
   my $which = shift;
   my $loud = shift || 0;
   return $loud ? uc $lines[$which] : $lines[$which];
 $bt = Text::BasicTemplate->new();
 $ss = "song: %&song(1,$loud)%, %&song(2,$loud)%, %&song(3,$loud)%";
 print $bt->parse(\$ss, { song => \&heart_of_oak, loud => 1 });

This would produce the lines of the song, separated by ", "; as written above (with loud == 1 in the dictionary), it will be shouted (inserted in capitals, as per the call to uc()) -- in the template, the use of $variable in a subroutine call indicates that $variable should be gotten from the dictionary rather than interpreted literally. Use of $ is not the normal BasicTemplate syntax -- %variable% would be more proper, but introduces a nasty parsing mess until the re engine gains balancing abilities (scheduled for perl5.6 as of this writing).

The argument $_bt_dict has special meaning, and will be replaced with the hashref being used as the active substitution dictionary, thus giving your routines access to it -- it will be passed in the form of a hashref, which you are free to alter during the call, so long as you keep the effects of your caching options in mind.

The available formatting of arguments passed to these subroutines is any combination of:

 word, word,
 word => word, word
 word => "word \"word\" 'word'"
 word => 'word "word"'
 word => "word\nword",

 # as in:
 %&mysubroutine(foo,bar,snaf => 3,str => "foo bar", word => 'k"ib"o', flap => "\"ing\"")%

In the first case, each word argument may contain anything but [,=>] (that is, a comma, an = or a >; yes, that is not entirely proper). If you need to use any of those characters, put the arguments in quotes. Parsing with quotations is more accurate, but depends on lookbehind assertions and is accordingly slow (the parse results are cached, so this is mostly an issue in repetitive executions rather than use of many instances in one template).

When performing database queries, which may return in increments and have separate beginning and ending operations, you can use three code references in a single list reference, for beginning, middle and end. The first will be called once at the beginning, the second repeatedly until it returns false, and the third once afterward. For example:

 sub $number_count = 10;
 sub numbers_start { "Countdown, kinda like BASIC: " }
 sub numbers_list { $number_count-- }
 sub numbers_end { "\"blastoff. whee.\"" }
 my %ov = (
   numbers => [ \&numbers_start, \&numbers_list, \&numbers_end ]
 $bt = Text::BasicTemplate->new();
 $ss = '%numbers%';
 print $bt->parse(\$ss,\%ov);

This would call &numbers_start and insert the result, then call and insert &numbers_list until it $number_count reached zero, then call &numbers_end once and insert that. This may easily be applied, for example, to an execute, fetch, fetch, fetch, ..., finish sequence in DBI. If you need only part of these three functions (e.g. a routine that does not need a finish function), you can pass any one as an empty code reference (e.g. \ sub { }).

The real use of subroutine references becomes apparent when you need the output from a function parsed into a template of its own. As noted above in the song() example, you can pass arguments to a subroutine via the template. This extends to passing hashes, e.g. %&foo(name => value)%, in which (name,value) will be passed to the subroutine referenced as foo in the parse() dictionary. You may also pass an argument (bt_template => filename), in which case the output from the coderef will be assumed to be a hashref; this hashref will then be added to the current parse() dictionary (where duplication occurs, the hashref will take precedence) and used as the dictionary given to a recursive call of parse() on the file specified by bt_template. So...

 sub start { 
   return "hello, ";
 my $pcount = 0;
 sub getname {
   my @people = ( { firstname => 'John', lastname => 'Doe' },
                  { firstname => 'Susan', lastname => 'Smith' }
   return $people[$pcount++];
 sub end {
   return "Nice to see you.";
 # assume that /path/hello-template contains
 # The Esteemed %firstname% %lastname%, Lord of All You Survey
 $bt = Text::BasicTemplate->new();
 $ss = "Greeting: \"%&greeting(bt_template => /path/hello-template)%\"";
 print $bt->parse(\$ss, { greeting => [ \&start, \&getname, \&end ] });

In this instance, the return values of &start and &end will be used as-is. &getname will be called until it reaches undef (on the third call); the hashrefs returned will be parsed into two copies of /tmp/hello-template. The final output would therefore be:

 hello, The Esteemed John Doe, Lord of All You Survey
 The Esteemed Susan Smith, Lord of All You Survey
 Nice to see you.

This has obvious usefulness in terms of taking database output and making presentable (e.g. HTML) output from it, amongst other uses.


Some basic pragma functions are provided for use in templates. These follow the same syntactical conventions as subroutine substitutions, but correspond to programs internal to Text::BasicTemplate rather than supplied by calling code. Pragmas should not be used on untrusted templates -- when templates are not trustworthy, they should be disabled by setting $object->{pragma_enable}->{name_of_pragma} to false, or more simply disabling all pragmas by setting $object->{pragma_enable} = {}. If an option pragma_enable is passed to new(), it will be taken as a substitute for the enabled list and not overridden.

Individual pragmas may be added or overridden with code of your own by setting $object->{pragma_functions}->{name_of_pragma} to a CODE reference. The referenced routine should expect to be passed a list containing a reference to the Text::BasicTemplate object, a hashref to the active dictionary (which may be {}), followed by any arguments passed in the template. Pragma routines must match ^bt_, or they will not be interpreted as pragmas.

Pragmas provided are as follows. Note that they follow, to a reasonable extent, the format given by the Apache 1.3 mod_include specification, with a few additions. Options in [ square brackets ] are optional.

bt_include({ file | virtual }, filename, [ noparse ])

Includes a file in the given location in the template. The first option specifies from where the file should be loaded, equivalent to the Apache mod_include form. file means any regular path and filename. virtual is interpreted as relative to $object->{include_document_root} or $ENV{DOCUMENT_ROOT} in that order of precedence; if no document root is specified, no include is done. semisecure is a restricted form of the file form, in which files must match \w[\w\-.]{0,254} to be included (this means, generally, that the included files must be in the working directory, unless you chdir() or something).

If noparse is supplied, the included file will be inserted as-is without further adjustment. Otherwise it will be run through parse() as would any normal template. You should use the noparse option when including an untrusted template from a trusted one.

bt_include() will only include readable regular files (that is, those passing -e, -f and -r). Note that this is suceptible to race conditions, so it does not confer any security where a race could be exploited by the usual file/symlink swapping.


  Includes the file, parses according to the active dictionary
  Includes the file but without any parsing on the way
  Includes the file index.html from the document_root directory,
  with parsing.

bt_include() is one the user might want to override if template files are stored in a database or other non-file mechanism.

bt_exec({ cmd | cgi }, command, parse)

Analogous to the Apache mod_include 'exec' directive. Executes the specified command and inserts its stdout output into the template in place of the directive. If parse is specified, this output will be handed to parse() as if it were a template file.

If cmd is given, the command will be read, parsed if selected, and inserted as-is without validation on the command. If cgi is given, the output will be skipped up and including the first blank line to remove HTTP headers.

bt_exec() is not secure and should not be used except with trusted templates and on trusted binaries. For this reason it is disabled by default and must be manually enabled by setting $object->{pragma_enable}->{bt_exec} true either when calling new() or subsequently.


Text::BasicTemplate 2.0 is a major rewrite from v0.9.8 and previous versions. Compatibility has been preserved to a degree, enough that with compatibility mode enabled, there should be no difference in either output or calling conventions.

Backwards-compatibility mode is enabled by default in v2.0, but will be disabled in some future version, possibly without notice.

Backwards compatibility is a concern in two respects, that of template format and calling conventions.


The BasicTemplate 2.0 template format is only minimally compatible with the older form. If your templates include conditionals or simple_ssi HTML-style include directives, you will need to update your templates and/or use compatibility mode. A template that uses only variable substitution (e.g. "Hello %name%") will not need compatibility mode.

Compatibility mode is enabled by passing 'compatibility_mode_0x => 1' to new() (see the POD for new()). Note that compatibility mode is slower than standard mode, because of conversion overhead.

The convert_template_0x_2x() function can convert a 0.x template to a 2.0 template -- see the POD for that function for the details. This function can easily be placed in a script to convert your templates in place, and it is likely that such a script will be provided with Text::BasicTemplate releases.


In general, there should be no necessary change between 0.x calls and 2.x calls. All the old calls have been replaced with stubs which call the new versions. These are roughly as follows:

 push(), parse_push() -- replaced by parse()
 print(), parse_print() -- replaced by print parse()
 list_cache() -- replaced by list_lexicon_cache()
 purge_cache() -- replaced by purge_*_cache()
 uncache() -- replaced by purge_lexicon_cache(), purge_file_cache()



Make a Text::BasicTemplate object. Syntax is as follows:

 $bt = Text::BasicTemplate->new(
  max_parse_recursion => 32,
  use_file_cache => 0,
  use_lexicon_cache => 1,
  use_scalarref_lexicon_cache => 0,
  use_full_cond_cache => 1,
  use_cond2rpn_cache => 1,
  use_dynroutine_arg_cache => 1,
  use_flock => 1,
  default_list_delimiter => ", ",
  default_hash_delimiter => ", ",
  default_hash_specifier => "=",
  default_undef_identifier => "",
  compatibility_mode_0x => 1,
  eval_subroutine_refs => 1,
  strip_html_comments => 0,
  strip_c_comments => 0,
  strip_cpp_comments => 0,
  strip_perl_comments => 0,
  condense_whitespace => 0,
  simple_ssi => 1

All explicit arguments to new() are optional; the values shown above are the defaults.

Configuration arguments given to new() have the following meanings:

max_parse_recursion: When performing a recursive parse() on a template, as in the case of a subroutine substitution with a bt_template parameter (see the SYNTAX section), parsing will stop if recursion goes more than this depth -- the typical cause would be a template A that included a subroutine reference that used a template B, which used a C, which used A again.
use_file_cache: Templates specified to parse() by filename are read into memory before being given to the lexer. If this option is set, the contents of the file will be cached in a hash after being read. This is largely unnecessary if (as per default) lexicon caching is enabled. Do not turn this on unless you have disabled lexicon caching, or are doing something dubious to the cache yourself.
use_lexicon_cache: If true, the lexicon generated from an input template will be cached prior to parsing. This is the normal form of caching, and enables subsequent calls to parse() to skip over the lexical parsing of templates, generally the most expensive part of the process.
use_scalarref_lexicon_cache: If true, the above lexicon caching applies to templates given to parse() via scalar reference, as well as by filename. This is generally fine, but if you pass the contents of multiple templates by a reference to the same scalar, you may get cache mismatching.
use_full_cond_cache: Controls caching of the results of evaluation of conditionals. Has three settings, off (0), normal (1), and persistent (2). If set off, every conditional will be reevaluated every time it is executed (this is not very expensive unless use_cond2rpn_cache is set off also; see documentation for that option). This is necessary only if you intend to change the values in the dictionary during a parse(), as in the case of a template-referenced subroutine calling a method that changes the dictionary. This cache adds some speed; the operation normally requires O(n) where n is the number of operators in the conditional, plus the cond2rpn conversion overhead, if applicable. When use_full_cond_cache is set to 1 (on, as per normal), conditionals are cached only for the span of one parse() call; if a template-referenced routine changes the dictionary for a variable already used in a conditional, the change will have no effect until the next call to parse(). When set to 2 (persistent), the conditional cache does not expire when parse() completes a single template, and indeed will not expire at all unless you call purge_fullcond_cache() manually. This setting can be useful for fast repeated parsing of the same data into multiple templates, but is not suitable when the dictionary is changing.
use_dynroutine_arg_cache: Subroutine substitutions in templates may be passed arguments; these arguments are parsed into a suitable list before being handed to the subroutine in question. If this is enabled, the results of that parsing will be cached to speed future use. This does not incur cache mismatches; leave enabled unless you have a good reason not to.
use_flock: If set true, template files will be flock()ed with a LOCK_SH while being read. Otherwise, they will be read blindly. Win32 afflictees might wish to disable this; in general, leave it alone. Note that files generally will need to be read only once each if either lexicon or file caching is enabled (see above).
default_list_delimiter: When listrefs are substituted into a template, they will be join()ed with the contents of $self->{list_delimiter}->{name} if defined, or with this default value otherwise. If you wish your listrefs contatenated with no delimiting, set this to ''. Default is ', '.
default_hash_delimiter: As above, but separates key/value pairs in hashref substitution. If %x = (y => z, x => p), this delimiter will be placed between y=z and x=p. Overridden by $self->{hash_delimiter}->{name}. Deault ', '.
default_hash_specifier: As above, separating keys and values in hashref substitution. In the above %x, this delimiter goes between y and z, and between x and p. Overriden by $self->{hash_specifier}->{name}. Default '='.
default_undef_identifier: When a template calls for a substitution key which is undefined in the dictionary, this value will be substituted instead. Default is ''. Something obvious like '**undefined**' might be a good choice for debugging purposes.
eval_subroutine_refs: This option enables evaluation of subroutine reference substitutions, e.g. %&myroutine()%. Generally a safe option, but you might want to disable it if parsing untrustworthy templates.
compatibility_mode_0x: Enables compatibility with templates written for Text::BasicTemplate v0.x. See COMPATIBILITY section.
strip_html_comments: If set true, HTML comments (<!-- ... -->) will be removed from the parse results. Note that nested comments are not properly stripped. Default off.
strip_c_comments: If true, C comments (/* ... */) will be removed from parse results. Default off.
strip_cpp_comments: If true, C and C++ comments (/* ... */ and // ...\n) will be removed from parse results. Default off.
strip_perl_comments: If true, perl and similar style comments (# ... \n) will be removed from parse results. Default off.
condense_whitespace: If true, whitespace in parse results will be condensed to the first byte of each, as would be done by most web browsers. Useful for tightening bandwidth usage on HTML templates without making the input templates themselves unreadable. Default off.
simple_ssi: If true, server-parsed HTML directives of the #include persuasion will have the file referenced in their file="" or virtual="" arguments inserted in their place. The form is <!--#include file="..."-->. This usage is deprecated in favor of the %&bt_include()% function -- see the SYNTAX section. Default off; this should not be enabled when using untrusted templates.

Given a source template in SOURCE_TEMPLATE, parses that template according to the key/value hash referenced by $ovr, then returns the result.

If SOURCE_TEMPLATE is given as a scalar, it will be interpreted as a filename, and the contents of that file will be read, parsed, and returned. If given as a scalar reference, it will be interpreted as a reference to a buffer containing the template (the referenced template will not be modified, and copies of the relevant parts will be used to build the lexicon). If SOURCE_TEMPLATE contains an array reference, that array will be used instead of generating a new lexicon.

If use_file_template_cache is true and the source template is loaded from a file, or if use_scalarref_lexicon_cache is true and the source template is given in a scalar reference, the lexicon will be cached to accelerate future parsing of the template. If the contents of either the file or the referenced buffer changes during the lifespan of the Text::BasicTemplate object, the code will not notice -- if you need to change the templates in this fashion, use uncache() to delete the cached lexicon. Lexicon references are not cached, since the code assumes if you make your own templates you are capable of caching them, too.

For templates stored in and loaded from files, note that they will be read and parsed in core, so you probably should not try to parse templates that would occupy a significant amount of your available memory. For large seldom-used templates, also consider disabling lexicon caching or calling uncache() afterwards.

OVR is a euphemism for some arbitrary combination of lists, scalar paris, hashrefs and listrefs. These should cumulatively amount to the substitution dictionary -- the simple form is { x => 'y' }, in which all %x% in the template will be replaced with y. (x,y) will work also (and by extension, you may pass lists of these, or raw hashes). The dictionary is parsed once, start-to-finish, so in the event of duplicated entries, the last entry of a given name will be the only one retained.

Note on backwards-compatibility: in v0.x, it was possible to pass scalars of the form "x=y". This is deprecated, and is only available if compatibility_mode_0x is set true. Further, as references are now legal fodder for substitutions, ("x",\%y) means that %x% will parse to the contents of %y -- if %y contains part of your substitution dictionary, then the above will present an error in any case, and ("x","y",\%y) is likely what you intended.

parse_range \@lexicon $start $end [ \@ov ]

Parses and returns the relevant parts of the specified lexicon over the given range. This has the happy side effect of eliminating the obnoxious passing around of chunks of the lexicon. Instead one need only pass references to a single lexicon and the range over which it should be parsed. This routine does the actual work of parse(), but is really only useful internally.

cond_evaluate CONDITIONAL [ \%ovr ]

Evaluates the specified conditional left-to-right. At present it does not handle operators also, just boolean/scalar evaluation.

identifier_evaluate $identifier \%ovr [ $type, $name ]

Evaluates the specified identifier and returns its value. Literals, being of the form \d+, "[...]" and '[...]', are returned as-is (leading and trailing quotes will be removed from string literals).

Identifiers of standard (no special type) form are returned as they appear in \%ovr; if those stored values are listrefs or hashrefs, they will be returned in formatted form -- listrefs will be returned as a scalar delimited by the value of $self->{list_delimiter}->{name}, hashes will be mapped into a scalar using $self->{hash_specifier}->{name} and $self->{hash_delimiter}->{name}, which three have the form ", ", "=" and ", " respectively by default.

Identifiers of the form $name will be checked against the environment variable of the same name, and if present, that value will be returned, otherwise undef will be returned.

Identififers of the form &name will be returned according to those entries in \%ovr of the form &name -- this is used to provide a separate namespace for substitutions, e.g. for CGI parameters.

Identifiers of the form !name will be evaluated according to the return value(s) from whatever stored procedure(s) have been registered under that name, if any. See store_dynroutine for details.

evaluate_dynroutine $name, $args, \%ovr

Evalutes a routine referenced by a template. The general form gives the name of the routine in $name (if no such named routine is available, returns undef), any arguments as a scalar $args, and the key-sub list in $ovr.

$args should be given as a scalar -- it will be parsed in parse_dynroutine_args and the result cached against future use.

parse_dynroutine_args $argstr

Pulls apart the argument string passed to a template-referenced dynamic routine, and returns a listref for it.

Format tolerance is only minimally clever. The formats tolerated are, in any combination:

 word, word,
 word => word, word
 word => "word \"word\" 'word'"
 word => 'word "word"'
 word => "word\nword",

In the first case, each word argument may contain anything but [,=>'"] (that is, ', ", =, or >; yes, that is not entirely proper). If you need to use any of those characters, put the arguments in quotes. Parsing with quotations is more accurate, but depends on lookbehind assertions and is accordingly slow (the parse results are cached, so this is mostly an issue in repetitive executions rather than use of many instances in one template).

evaluate_pragma $name, $args, \%ovr
is_identifier \$candidate

Takes a reference to a scalar containing a potential identifier. In a scalar context, returns 1 or 0. In a list context, returns (type,name) where type is one of the identififer type designators (&, !, $, etc) and name is the remainder of the identifier.

lex \$src

Splits the specified source buffer into a series of tokens, returns a listref to the resulting lexicon. See ABOUT for the details.

load_from_file $filename

Loads a template from the specified file. If use_file_cache is true, the file will be stored in the file cache (not necessary if caching is enabled for lexicons).

This code is very trusting concerning its filename -- the only check performed is to strip leading <, >, | and + signs to try to ensure that the filehandle obtained is read-only. Trailing pipes will be left alone, so that "/path/to/binary|" may use the output from 'binary'.

dump_lexicon \@lexicon [ $start_pos [ $end_pos ] ]

Returns a dump of the given lexicon. Principally used for debugging the module, or if you need to optimize templates to save lexical storage. If $start_pos/$end_pos are given, only that range of the lexical array is dumped.

dump_stack \@stack

Dumps the contents of a conditional-eval stack, which consists of a list of listrefs containing [ type, value ], type being one of the lexeme_types, value being either the identififer or an operator, depending on the type.


Lists the lexicons cached for files/scalars/etc.


Lists the files cached in the file cache. Empty unless use_file_cache is true.


Lists the conditional-to-RPN conversion cache. Empty if use_cond2rpn_cache is false.


Lists the contents of the conditional evaluation cache. Empty unless use_full_cond_cache is set true.


Tries to work out if taint checking is enabled, so that the right things can be enabled/disabled by new().

is_tainted SCALAR

Returns true if taint checking is enabled and the specified variable is tainted.


Activates debugging output.


Purges the given cache.


Compatibility function for BasicTemplate 0.x; synonym for list_lexicon_cache

push, parse_push

Compatibility functions for BasicTemplate 0.x; synonym for parse.

print, parse_print

Compatibility functions for BasicTempltae 0.x


Compatibility function for BasicTemplate 0.x; purges all applicable caches.

uncache FILE

Compatibility function for BasicTemplate 0.x; purges the specified file from the file and lexicon caches.

convert_template_0x_2x $buffer

Backwards-compatibility function for BasicTemplate 0.x; converts a template constructed for v0.x to v2.x. Used internally for conversions on-the-fly in backwards-compatible mode.

Note that this method will have no effect unless the 0.x template contains conditionals -- simple %key% substitutions are the same in both versions.


2.004: Fixed a dumb oversight in test suite where valid comparison strings assumed that the iteration order in a hash would be consistent and predictable. Passes make-test under perl5.6 now.

2.0: Major rewrite. Introduced lexical parsing, nested conditionals, list/hash formatting, subroutine references, operator evaluation and much other related stuff.

0.9.8: Added subroutine-reference parsing. This makes it possible to bind keys to subroutines which will be called (once per template) when needed; this can make things quicker if the template-specific informational requirements may not be easily predicted in advance.

0.9.7: Made stripping of lingering keys optional (default off); it was causing problems with URI-encoded substitutions, and in retrospect probably was not a good idea anyway. Thanks to Ian Baker <> for the bug report. Fixed stupid idiotic bug caused by overzealous optimization (some things were not meant to be done with references -- setting cache scalars, for iinstance). Renamed from ParsePrint to BasicTemplate for submission to CPAN. Fixed oversight wherein files inserted via simple_ssi #includes were having keys stripped, but not parsed first.

First fully public release. Hooray...

0.9.6: Rewrote argument handling in constructor the same way; deprecated old style arg passage.

0.9.5: Rewrote argument handling in parse_push to handle arbitrary combinations of different arg types. Fixed nasty bug that set the lvalue in comparison to the name of the entitity lvalue, not the value thereof.

0.9.4: Lots of optimizations. Inlined eval_conditional(), introduced caching of condititionals (parse-once, print repeatedly), other such changes. Approximately doubled output speed to about 3100 conditionals/sec on my i686-200 Linux box.

0.9.3: First stable, releaseable version. Much documentation.


Text::BasicTemplate is by Devin Carraway <>, originally written for Sonoma.Net in 1996. Maintained until v0.9.5 as ParsePrint, then Text::ParsePrint, then renamed for CPAN upload to Text::BasicTemplate. Assorted further assistance and debugging rendered by Ian Baker <> and Eric Eisenhart <>.


Copyright (c) 1996-1997 by Devin Carraway and Sonoma.Net. Copyright (c) 1997-1999 by Devin Carraway. Released under terms of the Perl Artistic License.

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 557:

'=item' outside of any '=over'

Around line 2215:

You forgot a '=back' before '=head1'