package SimpleTemplate;
use strict;
use warnings;
use vars qw( $VERSION );
$VERSION = '1.00';
my $default; # Holds the default template object when class methods ar
+e used.
sub new {
my $class = shift;
my $content = shift || _ST_default_content();
my $self = {
'_delims' => [qw/ <% %> /],
'_content' => $content,
'_listsep' => "\n",
};
bless $self, $class;
}
sub list_separator {
my $self = shift;
if (! ref $self) { $self = $default = $default || __PACKAGE__->new()
+ }
return @_ ? $self->{_listsep} = shift : $self->{_listsep};
}
sub delimiters {
my $self = shift;
if (! ref $self) { $self = $default = $default || __PACKAGE__->new()
+ }
$self->{_delims} = shift if @_ == 1;
$self->{_delims} = [shift, shift] if @_ == 2;
return $self->{_delims};
}
sub tags {
my $self = shift;
if (! ref $self) { $self = $default = $default || __PACKAGE__->new()
+ }
my ($L, $R) = @{$self->{_delims}};
my @list = $self->{_content} =~ m/\Q$L\E\s*(.*?)\s*\Q$R\E/gm;
return @list;
}
sub fill {
my $self = shift;
if (! ref $self) { $self = $default = $default || __PACKAGE__->new()
+ }
my $args = shift;
my $replace = shift;
my ($L, $R) = @{$self->{_delims}};
my $text = $self->{_content};
$text =~ s/\Q$L\E\s*(.*?)\s*\Q$R\E/$self->_expand($1,$args)/egm;
$self->{_content} = $text if $replace;
return \$text;
}
# Private Methods
sub _expand {
my $self = shift;
my ($key, $hashr) = @_;
my $value = $hashr->{$key};
return '' unless defined $value;
for (ref $value) {
/CODE/ and do { return $value->() };
/ARRAY/ and do { return join $self->{_listsep}, @$value };
/SCALAR/ and do { return $$value };
/^$/ and do { return $value };
}
}
# Private class methods
sub _ST_default_content {
my $FH;
my $pkg = caller;
no strict 'refs';
# if DATA exists in the calling package use that.
if ( exists ${ $pkg . '::' }{DATA} and defined *{${$pkg . '::'}{DATA
+}}{IO}) {
$FH = *{${$pkg . '::'}{DATA}}{IO};
# else if DATA exists in main, use that.
} elsif ( exists $main::{DATA} and defined *main::DATA{IO} ){
$FH = *main::DATA{IO};
# else use <>
} else {
$FH = \*ARGV;
}
do { undef $/; <$FH> };
}
q( My two cents aren't worth a dime. );
__END__
=head1 NAME
SimpleTemplate - Perl extension for very simple templates.
=head1 SYNOPSIS
use SimpleTemplate;
my $template = SimpleTemplate->new("Hello, <%World%>!\n");
my $ref = $template->fill({ World => 'PerlMonks' });
print $$ref
exit(0);
# Also try the bells, whistles, and variations! Like...
# Filling placeholders with other thingies!
my $textref = $template->fill( { Foo => \$scalar_ref,
Bar => \@or_a_list,
Baz => \&a_sub_ref, } );
# Default Content!
my $template = SimpleTemplate->new();
# Default Content via a class method!
SimpleTemplate->fill({ PlaceHolder => 'Your Favorite Value' });
# Change your delimiters!
$template->delimiters('[:', ':]');
# Change your list separator!
$template->list_separator(':');
# Find the tag names in your Content!
my @tags = $template->tags();
=head1 DESCRIPTION
This module allows for filling in placeholders in templates. It is mea
+nt to
exceedingly simple. It does not make it possible for you to actually p
+ut code
in your templates. If that is what you want, there are many other (les
+s simple)
modules that would be a better choice.
SimpleTemplate works in two (intermixable) modes. When the provided me
+thods are
called as class methods, they operate on a default template object sto
+red in a
private class variable. This default template is created the first tim
+e any of
the methods are called as class methods. It is created by calling the
constructor without any arguments.
I've found this module to be extreeeeeeeeeeeeeeeeeeeeeeeemely useful.
+I use it
for all manner of things. Here's a hint... just because SimpleTemplate
+ is
simple that doesn't mean your use of it has to be. SimpleTemplate can
+do a lot,
especially if you make heavy use of the delimiters() method and the op
+tional
argument to fill().
=head1 METHODS
=over 8
=item new()
The constructor can be called with either a single scalar argument or
+none at
all. When it is called with an argument, the argument is taken to be t
+he
template content. When it is called without an argument, the template
+content
is read from a filehandle. If the DATA filehandle is found in the call
+ing
package, the template content is read from it. Else if the DATA fileha
+ndle is
found in main::, the template content is read from there. Otherwise, t
+he
template content is read from the ARGV filehandle.
=item fill()
This method expects a single hashref as an argument. The keys of the h
+ash
referred to by the hashref should coincide with the placeholder names
+and the
values should be the data to be substituted (or references to the data
+.) If a
value is found to be a reference, it will be called if it is a code re
+ference,
dereferenced and joined with the defined list separator if it is a ref
+erence to
an array, or dereferenced if it is a reference to a scalar. Note that
+a
reference to a hash isn't handled specially at all. An optional argume
+nt can
be supplied. If it is a true value, the template object's content will
+ be
replaced with the result of filling in its placeholders. This can be u
+seful for
recursively filling templates.
=item delimiters()
This method takes 0, 1, or 2 arguments. When called with at least
one argument, it sets the delimiters used to define placeholders in th
+e
template. If there is exactly one argument, it is assumed to be a refe
+rence to
an array containing the left and right delimiters in that order. When
+called
with two arguments, they are assumed to be the left and right delimite
+rs in
that order. When called with no arguments no attempt is made to set t
+he
delimiters. This method returns a reference to an array containing the
+ left and
right delimiters in that order. The default delimiters are '<%' and '%
+>' but
feel free to change them; that's what this method is here for.
=item list_separator()
This method takes either 0 arguments or exactly one argument.
If it is called with an argument, the list separator value is set to t
+hat
value. It returns the list separator value. By default, the list separ
+ator is a
newline ("\n"). The list separator is a string which is used to separa
+te the
values when a placeholder is filled with an array.
=item tags()
This method takes no arguments. It returns a list of the placeholder n
+ames
used in the template.
=back
=head1 IMPORTANT NOTE
Placeholder names must not have leading/trailing whitespace. Whitespac
+e should
be avoided in delimiters too.
=head1 LIMITATIONS
SimpleTemplate reads the whole template into memory. If your templates
+ are
huge, it will be a memory hog. This helps to keep SimpleTemplate SIMPL
+E!
=head1 BUGS
Yeah, right! As if... Look - this module is just too simple to have bu
+gs.
But, if you find any anyway, please let me know at perlmonks.org.
=head1 AUTHOR
sauoq
=head1 SEE ALSO
L<perl>.
=cut
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.