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 =head1 AUTHOR sauoq =head1 SEE ALSO L<perl>. =cut

In reply to But... SimpleTemplate really is. by sauoq

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.