# -*- perl -*-
# Text::Template.pm
#
# Fill in `templates'
#
# Copyright 2013 M. J. Dominus.
# You may copy and distribute this program under the
# same terms as Perl itself.
# If in doubt, write to mjd-perl-template+@plover.com for a license.
#
package Text::Template;
$Text::Template::VERSION = '1.59';
# ABSTRACT: Expand template text with embedded Perl
use strict;
use warnings;
require 5.008;
use base 'Exporter';
our @EXPORT_OK = qw(fill_in_file fill_in_string TTerror);
our $ERROR;
my %GLOBAL_PREPEND = ('Text::Template' => '');
sub Version {
$Text::Template::VERSION;
}
sub _param {
my ($k, %h) = @_;
for my $kk ($k, "\u$k", "\U$k", "-$k", "-\u$k", "-\U$k") {
return $h{$kk} if exists $h{$kk};
}
return undef;
}
sub always_prepend {
my $pack = shift;
my $old = $GLOBAL_PREPEND{$pack};
$GLOBAL_PREPEND{$pack} = shift;
$old;
}
{
my %LEGAL_TYPE;
BEGIN {
%LEGAL_TYPE = map { $_ => 1 } qw(FILE FILEHANDLE STRING ARRAY);
}
sub new {
my ($pack, %a) = @_;
my $stype = uc(_param('type', %a) || "FILE");
my $source = _param('source', %a);
my $untaint = _param('untaint', %a);
my $prepend = _param('prepend', %a);
my $alt_delim = _param('delimiters', %a);
my $broken = _param('broken', %a);
my $encoding = _param('encoding', %a);
unless (defined $source) {
require Carp;
Carp::croak("Usage: $ {pack}::new(TYPE => ..., SOURCE => ...)");
}
unless ($LEGAL_TYPE{$stype}) {
require Carp;
Carp::croak("Illegal value `$stype' for TYPE parameter");
}
my $self = {
TYPE => $stype,
PREPEND => $prepend,
UNTAINT => $untaint,
BROKEN => $broken,
ENCODING => $encoding,
(defined $alt_delim ? (DELIM => $alt_delim) : ())
};
# Under 5.005_03, if any of $stype, $prepend, $untaint, or $broken
# are tainted, all the others become tainted too as a result of
# sharing the expression with them. We install $source separately
# to prevent it from acquiring a spurious taint.
$self->{SOURCE} = $source;
bless $self => $pack;
return unless $self->_acquire_data;
$self;
}
}
# Convert template objects of various types to type STRING,
# in which the template data is embedded in the object itself.
sub _acquire_data {
my $self = shift;
my $type = $self->{TYPE};
if ($type eq 'STRING') {
# nothing necessary
}
elsif ($type eq 'FILE') {
my $data = _load_text($self->{SOURCE});
unless (defined $data) {
# _load_text already set $ERROR
return undef;
}
if ($self->{UNTAINT} && _is_clean($self->{SOURCE})) {
_unconditionally_untaint($data);
}
if (defined $self->{ENCODING}) {
require Encode;
$data = Encode::decode($self->{ENCODING}, $data, &Encode::FB_CROAK);
}
$self->{TYPE} = 'STRING';
$self->{FILENAME} = $self->{SOURCE};
$self->{SOURCE} = $data;
}
elsif ($type eq 'ARRAY') {
$self->{TYPE} = 'STRING';
$self->{SOURCE} = join '', @{ $self->{SOURCE} };
}
elsif ($type eq 'FILEHANDLE') {
$self->{TYPE} = 'STRING';
local $/;
my $fh = $self->{SOURCE};
my $data = <$fh>; # Extra assignment avoids bug in Solaris perl5.00[45].
if ($self->{UNTAINT}) {
_unconditionally_untaint($data);
}
$self->{SOURCE} = $data;
}
else {
# This should have been caught long ago, so it represents a
# drastic `can't-happen' sort of failure
my $pack = ref $self;
die "Can only acquire data for $pack objects of subtype STRING, but this is $type; aborting";
}
$self->{DATA_ACQUIRED} = 1;
}
sub source {
my $self = shift;
$self->_acquire_data unless $self->{DATA_ACQUIRED};
return $self->{SOURCE};
}
sub set_source_data {
my ($self, $newdata, $type) = @_;
$self->{SOURCE} = $newdata;
$self->{DATA_ACQUIRED} = 1;
$self->{TYPE} = $type || 'STRING';
1;
}
sub compile {
my $self = shift;
return 1 if $self->{TYPE} eq 'PREPARSED';
return undef unless $self->_acquire_data;
unless ($self->{TYPE} eq 'STRING') {
my $pack = ref $self;
# This should have been caught long ago, so it represents a
# drastic `can't-happen' sort of failure
die "Can only compile $pack objects of subtype STRING, but this is $self->{TYPE}; aborting";
}
my @tokens;
my $delim_pats = shift() || $self->{DELIM};
my ($t_open, $t_close) = ('{', '}');
my $DELIM; # Regex matches a delimiter if $delim_pats
if (defined $delim_pats) {
($t_open, $t_close) = @$delim_pats;
$DELIM = "(?:(?:\Q$t_open\E)|(?:\Q$t_close\E))";
@tokens = split /($DELIM|\n)/, $self->{SOURCE};
}
else {
@tokens = split /(\\\\(?=\\*[{}])|\\[{}]|[{}\n])/, $self->{SOURCE};
}
my $state = 'TEXT';
my $depth = 0;
my $lineno = 1;
my @content;
my $cur_item = '';
my $prog_start;
while (@tokens) {
my $t = shift @tokens;
next if $t eq '';
if ($t eq $t_open) { # Brace or other opening delimiter
if ($depth == 0) {
push @content, [ $state, $cur_item, $lineno ] if $cur_item ne '';
$cur_item = '';
$state = 'PROG';
$prog_start = $lineno;
}
else {
$cur_item .= $t;
}
$depth++;
}
elsif ($t eq $t_close) { # Brace or other closing delimiter
$depth--;
if ($depth < 0) {
$ERROR = "Unmatched close brace at line $lineno";
return undef;
}
elsif ($depth == 0) {
push @content, [ $state, $cur_item, $prog_start ] if $cur_item ne '';
$state = 'TEXT';
$cur_item = '';
}
else {
$cur_item .= $t;
}
}
elsif (!$delim_pats && $t eq '\\\\') { # precedes \\\..\\\{ or \\\..\\\}
$cur_item .= '\\';
}
elsif (!$delim_pats && $t =~ /^\\([{}])$/) { # Escaped (literal) brace?
$cur_item .= $1;
}
elsif ($t eq "\n") { # Newline
$lineno++;
$cur_item .= $t;
}
else { # Anything else
$cur_item .= $t;
}
}
if ($state eq 'PROG') {
$ERROR = "End of data inside program text that began at line $prog_start";
return undef;
}
elsif ($state eq 'TEXT') {
push @content, [ $state, $cur_item, $lineno ] if $cur_item ne '';
}
else {
die "Can't happen error #1";
}
$self->{TYPE} = 'PREPARSED';
$self->{SOURCE} = \@content;
1;
}
sub prepend_text {
my $self = shift;
my $t = $self->{PREPEND};
unless (defined $t) {
$t = $GLOBAL_PREPEND{ ref $self };
unless (defined $t) {
$t = $GLOBAL_PREPEND{'Text::Template'};
}
}
$self->{PREPEND} = $_[1] if $#_ >= 1;
return $t;
}
sub fill_in {
my ($fi_self, %fi_a) = @_;
unless ($fi_self->{TYPE} eq 'PREPARSED') {
my $delims = _param('delimiters', %fi_a);
my @delim_arg = (defined $delims ? ($delims) : ());
$fi_self->compile(@delim_arg)
or return undef;
}
my $fi_varhash = _param('hash', %fi_a);
my $fi_package = _param('package', %fi_a);
my $fi_broken = _param('broken', %fi_a) || $fi_self->{BROKEN} || \&_default_broken;
my $fi_broken_arg = _param('broken_arg', %fi_a) || [];
my $fi_safe = _param('safe', %fi_a);
my $fi_ofh = _param('output', %fi_a);
my $fi_filename = _param('filename', %fi_a) || $fi_self->{FILENAME} || 'template';
my $fi_strict = _param('strict', %fi_a);
my $fi_prepend = _param('prepend', %fi_a);
my $fi_eval_package;
my $fi_scrub_package = 0;
unless (defined $fi_prepend) {
$fi_prepend = $fi_self->prepend_text;
}
if (defined $fi_safe) {
$fi_eval_package = 'main';
}
elsif (defined $fi_package) {
$fi_eval_package = $fi_package;
}
elsif (defined $fi_varhash) {
$fi_eval_package = _gensym();
$fi_scrub_package = 1;
}
else {
$fi_eval_package = caller;
}
my @fi_varlist;
my $fi_install_package;
if (defined $fi_varhash) {
if (defined $fi_package) {
$fi_install_package = $fi_package;
}
elsif (defined $fi_safe) {
$fi_install_package = $fi_safe->root;
}
else {
$fi_install_package = $fi_eval_package; # The gensymmed one
}
@fi_varlist = _install_hash($fi_varhash => $fi_install_package);
if ($fi_strict) {
$fi_prepend = "use vars qw(@fi_varlist);$fi_prepend" if @fi_varlist;
$fi_prepend = "use strict;$fi_prepend";
}
}
if (defined $fi_package && defined $fi_safe) {
no strict 'refs';
# Big fat magic here: Fix it so that the user-specified package
# is the default one available in the safe compartment.
*{ $fi_safe->root . '::' } = \%{ $fi_package . '::' }; # LOD
}
my $fi_r = '';
my $fi_item;
foreach $fi_item (@{ $fi_self->{SOURCE} }) {
my ($fi_type, $fi_text, $fi_lineno) = @$fi_item;
if ($fi_type eq 'TEXT') {
$fi_self->append_text_to_output(
text => $fi_text,
handle => $fi_ofh,
out => \$fi_r,
type => $fi_type,);
}
elsif ($fi_type eq 'PROG') {
no strict;
my $fi_lcomment = "#line $fi_lineno $fi_filename";
my $fi_progtext = "package $fi_eval_package; $fi_prepend;\n$fi_lcomment\n$fi_text;\n;";
my $fi_res;
my $fi_eval_err = '';
if ($fi_safe) {
no strict;
no warnings;
$fi_safe->reval(q{undef $OUT});
$fi_res = $fi_safe->reval($fi_progtext);
$fi_eval_err = $@;
my $OUT = $fi_safe->reval('$OUT');
$fi_res = $OUT if defined $OUT;
}
else {
no strict;
no warnings;
my $OUT;
$fi_res = eval $fi_progtext;
$fi_eval_err = $@;
$fi_res = $OUT if defined $OUT;
}
# If the value of the filled-in text really was undef,
# change it to an explicit empty string to avoid undefined
# value warnings later.
$fi_res = '' unless defined $fi_res;
if ($fi_eval_err) {
$fi_res = $fi_broken->(
text => $fi_text,
error => $fi_eval_err,
lineno => $fi_lineno,
arg => $fi_broken_arg,);
if (defined $fi_res) {
$fi_self->append_text_to_output(
text => $fi_res,
handle => $fi_ofh,
out => \$fi_r,
type => $fi_type,);
}
else {
return $fi_r; # Undefined means abort processing
}
}
else {
$fi_self->append_text_to_output(
text => $fi_res,
handle => $fi_ofh,
out => \$fi_r,
type => $fi_type,);
}
}
else {
die "Can't happen error #2";
}
}
_scrubpkg($fi_eval_package) if $fi_scrub_package;
defined $fi_ofh ? 1 : $fi_r;
}
sub append_text_to_output {
my ($self, %arg) = @_;
if (defined $arg{handle}) {
print { $arg{handle} } $arg{text};
}
else {
${ $arg{out} } .= $arg{text};
}
return;
}
sub fill_this_in {
my ($pack, $text) = splice @_, 0, 2;
my $templ = $pack->new(TYPE => 'STRING', SOURCE => $text, @_)
or return undef;
$templ->compile or return undef;
my $result = $templ->fill_in(@_);
$result;
}
sub fill_in_string {
my $string = shift;
my $package = _param('package', @_);
push @_, 'package' => scalar(caller) unless defined $package;
Text::Template->fill_this_in($string, @_);
}
sub fill_in_file {
my $fn = shift;
my $templ = Text::Template->new(TYPE => 'FILE', SOURCE => $fn, @_) or return undef;
$templ->compile or return undef;
my $text = $templ->fill_in(@_);
$text;
}
sub _default_broken {
my %a = @_;
my $prog_text = $a{text};
my $err = $a{error};
my $lineno = $a{lineno};
chomp $err;
# $err =~ s/\s+at .*//s;
"Program fragment delivered error ``$err''";
}
sub _load_text {
my $fn = shift;
open my $fh, '<', $fn or do {
$ERROR = "Couldn't open file $fn: $!";
return undef;
};
local $/;
<$fh>;
}
sub _is_clean {
my $z;
eval { ($z = join('', @_)), eval '#' . substr($z, 0, 0); 1 } # LOD
}
sub _unconditionally_untaint {
for (@_) {
($_) = /(.*)/s;
}
}
{
my $seqno = 0;
sub _gensym {
__PACKAGE__ . '::GEN' . $seqno++;
}
sub _scrubpkg {
my $s = shift;
$s =~ s/^Text::Template:://;
no strict 'refs';
my $hash = $Text::Template::{ $s . "::" };
foreach my $key (keys %$hash) {
undef $hash->{$key};
}
%$hash = ();
delete $Text::Template::{ $s . "::" };
}
}
# Given a hashful of variables (or a list of such hashes)
# install the variables into the specified package,
# overwriting whatever variables were there before.
sub _install_hash {
my $hashlist = shift;
my $dest = shift;
if (UNIVERSAL::isa($hashlist, 'HASH')) {
$hashlist = [$hashlist];
}
my @varlist;
for my $hash (@$hashlist) {
for my $name (keys %$hash) {
my $val = $hash->{$name};
no strict 'refs';
no warnings 'redefine';
local *SYM = *{"$ {dest}::$name"};
if (!defined $val) {
delete ${"$ {dest}::"}{$name};
my $match = qr/^.\Q$name\E$/;
@varlist = grep { $_ !~ $match } @varlist;
}
elsif (ref $val) {
*SYM = $val;
push @varlist, do {
if (UNIVERSAL::isa($val, 'ARRAY')) { '@' }
elsif (UNIVERSAL::isa($val, 'HASH')) { '%' }
else { '$' }
}
. $name;
}
else {
*SYM = \$val;
push @varlist, '$' . $name;
}
}
}
@varlist;
}
sub TTerror { $ERROR }
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Text::Template - Expand template text with embedded Perl
=head1 VERSION
version 1.59
=head1 SYNOPSIS
use Text::Template;
$template = Text::Template->new(TYPE => 'FILE', SOURCE => 'filename.tmpl');
$template = Text::Template->new(TYPE => 'ARRAY', SOURCE => [ ... ] );
$template = Text::Template->new(TYPE => 'FILEHANDLE', SOURCE => $fh );
$template = Text::Template->new(TYPE => 'STRING', SOURCE => '...' );
$template = Text::Template->new(PREPEND => q{use strict;}, ...);
# Use a different template file syntax:
$template = Text::Template->new(DELIMITERS => [$open, $close], ...);
$recipient = 'King';
$text = $template->fill_in(); # Replaces `{$recipient}' with `King'
print $text;
$T::recipient = 'Josh';
$text = $template->fill_in(PACKAGE => T);
# Pass many variables explicitly
$hash = { recipient => 'Abed-Nego',
friends => [ 'me', 'you' ],
enemies => { loathsome => 'Saruman',
fearsome => 'Sauron' },
};
$text = $template->fill_in(HASH => $hash, ...);
# $recipient is Abed-Nego,
# @friends is ( 'me', 'you' ),
# %enemies is ( loathsome => ..., fearsome => ... )
# Call &callback in case of programming errors in template
$text = $template->fill_in(BROKEN => \&callback, BROKEN_ARG => $ref, ...);
# Evaluate program fragments in Safe compartment with restricted permissions
$text = $template->fill_in(SAFE => $compartment, ...);
# Print result text instead of returning it
$success = $template->fill_in(OUTPUT => \*FILEHANDLE, ...);
# Parse template with different template file syntax:
$text = $template->fill_in(DELIMITERS => [$open, $close], ...);
# Note that this is *faster* than using the default delimiters
# Prepend specified perl code to each fragment before evaluating:
$text = $template->fill_in(PREPEND => q{use strict 'vars';}, ...);
use Text::Template 'fill_in_string';
$text = fill_in_string( <<'EOM', PACKAGE => 'T', ...);
Dear {$recipient},
Pay me at once.
Love,
G.V.
EOM
use Text::Template 'fill_in_file';
$text = fill_in_file($filename, ...);
# All templates will always have `use strict vars' attached to all fragments
Text::Template->always_prepend(q{use strict 'vars';});
=head1 DESCRIPTION
This is a library for generating form letters, building HTML pages, or
filling in templates generally. A `template' is a piece of text that
has little Perl programs embedded in it here and there. When you
`fill in' a template, you evaluate the little programs and replace
them with their values.
You can store a template in a file outside your program. People can
modify the template without modifying the program. You can separate
the formatting details from the main code, and put the formatting
parts of the program into the template. That prevents code bloat and
encourages functional separation.
=head2 Example
Here's an example of a template, which we'll suppose is stored in the
file C:
Dear {$title} {$lastname},
It has come to our attention that you are delinquent in your
{$monthname[$last_paid_month]} payment. Please remit
${sprintf("%.2f", $amount)} immediately, or your patellae may
be needlessly endangered.
Love,
Mark "Vizopteryx" Dominus
The result of filling in this template is a string, which might look
something like this:
Dear Mr. Smith,
It has come to our attention that you are delinquent in your
February payment. Please remit
$392.12 immediately, or your patellae may
be needlessly endangered.
Love,
Mark "Vizopteryx" Dominus
Here is a complete program that transforms the example
template into the example result, and prints it out:
use Text::Template;
my $template = Text::Template->new(SOURCE => 'formletter.tmpl')
or die "Couldn't construct template: $Text::Template::ERROR";
my @monthname = qw(January February March April May June
July August September October November December);
my %vars = (title => 'Mr.',
firstname => 'John',
lastname => 'Smith',
last_paid_month => 1, # February
amount => 392.12,
monthname => \@monthname);
my $result = $template->fill_in(HASH => \%vars);
if (defined $result) { print $result }
else { die "Couldn't fill in template: $Text::Template::ERROR" }
=head2 Philosophy
When people make a template module like this one, they almost always
start by inventing a special syntax for substitutions. For example,
they build it so that a string like C<%%VAR%%> is replaced with the
value of C<$VAR>. Then they realize the need extra formatting, so
they put in some special syntax for formatting. Then they need a
loop, so they invent a loop syntax. Pretty soon they have a new
little template language.
This approach has two problems: First, their little language is
crippled. If you need to do something the author hasn't thought of,
you lose. Second: Who wants to learn another language? You already
know Perl, so why not use it?
C templates are programmed in I. You embed Perl
code in your template, with C<{> at the beginning and C<}> at the end.
If you want a variable interpolated, you write it the way you would in
Perl. If you need to make a loop, you can use any of the Perl loop
constructions. All the Perl built-in functions are available.
=head1 Details
=head2 Template Parsing
The C module scans the template source. An open brace
C<{> begins a program fragment, which continues until the matching
close brace C<}>. When the template is filled in, the program
fragments are evaluated, and each one is replaced with the resulting
value to yield the text that is returned.
A backslash C<\> in front of a brace (or another backslash that is in
front of a brace) escapes its special meaning. The result of filling
out this template:
\{ The sum of 1 and 2 is {1+2} \}
is
{ The sum of 1 and 2 is 3 }
If you have an unmatched brace, C will return a
failure code and a warning about where the problem is. Backslashes
that do not precede a brace are passed through unchanged. If you have
a template like this:
{ "String that ends in a newline.\n" }
The backslash inside the string is passed through to Perl unchanged,
so the C<\n> really does turn into a newline. See the note at the end
for details about the way backslashes work. Backslash processing is
I done when you specify alternative delimiters with the
C option. (See L<"Alternative Delimiters">, below.)
Each program fragment should be a sequence of Perl statements, which
are evaluated the usual way. The result of the last statement
executed will be evaluated in scalar context; the result of this
statement is a string, which is interpolated into the template in
place of the program fragment itself.
The fragments are evaluated in order, and side effects from earlier
fragments will persist into later fragments:
{$x = @things; ''}The Lord High Chamberlain has gotten {$x}
things for me this year.
{ $diff = $x - 17;
$more = 'more'
if ($diff == 0) {
$diff = 'no';
} elsif ($diff < 0) {
$more = 'fewer';
}
'';
}
That is {$diff} {$more} than he gave me last year.
The value of C<$x> set in the first line will persist into the next
fragment that begins on the third line, and the values of C<$diff> and
C<$more> set in the second fragment will persist and be interpolated
into the last line. The output will look something like this:
The Lord High Chamberlain has gotten 42
things for me this year.
That is 25 more than he gave me last year.
That is all the syntax there is.
=head2 The C<$OUT> variable
There is one special trick you can play in a template. Here is the
motivation for it: Suppose you are going to pass an array, C<@items>,
into the template, and you want the template to generate a bulleted
list with a header, like this:
Here is a list of the things I have got for you since 1907:
* Ivory
* Apes
* Peacocks
* ...
One way to do it is with a template like this:
Here is a list of the things I have got for you since 1907:
{ my $blist = '';
foreach $i (@items) {
$blist .= qq{ * $i\n};
}
$blist;
}
Here we construct the list in a variable called C<$blist>, which we
return at the end. This is a little cumbersome. There is a shortcut.
Inside of templates, there is a special variable called C<$OUT>.
Anything you append to this variable will appear in the output of the
template. Also, if you use C<$OUT> in a program fragment, the normal
behavior, of replacing the fragment with its return value, is
disabled; instead the fragment is replaced with the value of C<$OUT>.
This means that you can write the template above like this:
Here is a list of the things I have got for you since 1907:
{ foreach $i (@items) {
$OUT .= " * $i\n";
}
}
C<$OUT> is reinitialized to the empty string at the start of each
program fragment. It is private to C, so
you can't use a variable named C<$OUT> in your template without
invoking the special behavior.
=head2 General Remarks
All C functions return C on failure, and set the
variable C<$Text::Template::ERROR> to contain an explanation of what
went wrong. For example, if you try to create a template from a file
that does not exist, C<$Text::Template::ERROR> will contain something like:
Couldn't open file xyz.tmpl: No such file or directory
=head2 C
$template = Text::Template->new( TYPE => ..., SOURCE => ... );
This creates and returns a new template object. C returns
C and sets C<$Text::Template::ERROR> if it can't create the
template object. C says where the template source code will
come from. C says what kind of object the source is.
The most common type of source is a file:
Text::Template->new( TYPE => 'FILE', SOURCE => $filename );
This reads the template from the specified file. The filename is
opened with the Perl C command, so it can be a pipe or anything
else that makes sense with C.
The C can also be C, in which case the C should
be a string:
Text::Template->new( TYPE => 'STRING',
SOURCE => "This is the actual template!" );
The C can be C, in which case the source should be a
reference to an array of strings. The concatenation of these strings
is the template:
Text::Template->new( TYPE => 'ARRAY',
SOURCE => [ "This is ", "the actual",
" template!",
]
);
The C can be FILEHANDLE, in which case the source should be an
open filehandle (such as you got from the C or C
packages, or a glob, or a reference to a glob). In this case
C will read the text from the filehandle up to
end-of-file, and that text is the template:
# Read template source code from STDIN:
Text::Template->new ( TYPE => 'FILEHANDLE',
SOURCE => \*STDIN );
If you omit the C attribute, it's taken to be C.
C is required. If you omit it, the program will abort.
The words C and C can be spelled any of the following ways:
TYPE SOURCE
Type Source
type source
-TYPE -SOURCE
-Type -Source
-type -source
Pick a style you like and stick with it.
=over 4
=item C
You may also add a C option. If this option is present,
its value should be a reference to an array of two strings. The first
string is the string that signals the beginning of each program
fragment, and the second string is the string that signals the end of
each program fragment. See L<"Alternative Delimiters">, below.
=item C
You may also add a C option. If this option is present, and the
C is a C, then the data will be decoded from the given encoding
using the L module. You can use any encoding that L recognizes.
E.g.:
Text::Template->new(
TYPE => 'FILE',
ENCODING => 'UTF-8',
SOURCE => 'xyz.tmpl');
=item C
If your program is running in taint mode, you may have problems if
your templates are stored in files. Data read from files is
considered 'untrustworthy', and taint mode will not allow you to
evaluate the Perl code in the file. (It is afraid that a malicious
person might have tampered with the file.)
In some environments, however, local files are trustworthy. You can
tell C that a certain file is trustworthy by supplying
C 1> in the call to C. This will tell
C to disable taint checks on template code that has
come from a file, as long as the filename itself is considered
trustworthy. It will also disable taint checks on template code that
comes from a filehandle. When used with C 'string'> or C 'array'>, it has no effect.
See L for more complete information about tainting.
Thanks to Steve Palincsar, Gerard Vreeswijk, and Dr. Christoph Baehr
for help with this feature.
=item C
This option is passed along to the C call unless it is
overridden in the arguments to C. See L feature
and using C in templates> below.
=item C
This option is passed along to the C call unless it is
overridden in the arguments to C. See L> below.
=back
=head2 C
$template->compile()
Loads all the template text from the template's source, parses and
compiles it. If successful, returns true; otherwise returns false and
sets C<$Text::Template::ERROR>. If the template is already compiled,
it returns true and does nothing.
You don't usually need to invoke this function, because C
(see below) compiles the template if it isn't compiled already.
If there is an argument to this function, it must be a reference to an
array containing alternative delimiter strings. See C<"Alternative
Delimiters">, below.
=head2 C
$template->fill_in(OPTIONS);
Fills in a template. Returns the resulting text if successful.
Otherwise, returns C and sets C<$Text::Template::ERROR>.
The I are a hash, or a list of key-value pairs. You can
write the key names in any of the six usual styles as above; this
means that where this manual says C (for example) you can
actually use any of
PACKAGE Package package -PACKAGE -Package -package
Pick a style you like and stick with it. The all-lowercase versions
may yield spurious warnings about
Ambiguous use of package => resolved to "package"
so you might like to avoid them and use the capitalized versions.
At present, there are eight legal options: C, C,
C, C, C, C, C