Path: usenet.cis.ufl.edu!usenet.eel.ufl.edu!psgrain!nntp.teleport.com!usenet
From: [email protected] (Mark-Jason Dominus)
Newsgroups: comp.lang.perl.announce,comp.lang.perl.misc
Subject: Text::Template (Construct text from template with blanks)
Followup-To: comp.lang.perl.misc
Date: 28 Dec 1995 21:19:47 GMT
Organization: Plover Systems
Lines: 375
Approved: [email protected] (comp.lang.perl.announce)
Message-ID: <[email protected]>
NNTP-Posting-Host: kelly.teleport.com
Keywords: alveolus coeditor mayapple noise
X-Disclaimer: The "Approved" header verifies header information for article transmission and does not imply approval of content.
Xref: usenet.cis.ufl.edu comp.lang.perl.announce:214 comp.lang.perl.misc:15737



TEXT::TEMPLATE VERSION 0.1 alpha
28 December, 1995

SHORT DESCRIPTION

This module is for filling in templates.  A template is an ordinary
piece of text with tiny Perl programs and variables embedded in it.
When a template is `filled in', the Perl programs and variables are
evaluated, and replaced with their values.

This is useful for generating all sorts of program output, including
HTML pages and error messages.

Templates can reside in files external to the program that is filling
them in, and they can be modified and maintained by persons unfamiliar
with Perl, because the Perl parts of a template are encapsulated.

Full docmuentation appears at the end of this message.

COPYRIGHT

The Text::Template module is Copyright 1995 Mark-Jason Dominus.
You may use, modify, copy, and distribute it under the same terms as
Perl itself.

PREREQUISITES

Exporter.

WHERE TO GET IT

CPAN:
        .../authors/Mark-Jason_Dominus/Text-Template-0.1a.tar.gz

See http://www.perl.com/perl/CPAN/CPAN.html for a list of CPAN sites.

For example:

       ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/Mark-Jason_Dominus/Text-Template-0.1a.tar.gz


HOW TO BUILD AND INSTALL

       perl Makefile.PL
       make
       make install

No `test's yet; sorry.

RECENT CHANGES

This is the first general release.

This is an ALPHA release.  Future changes are very likely.  Future
incompatible changes are likely.

BUGS TO

Mark-Jason Dominus, Plover Systems
[email protected]

COMPLETE DOCUMENTATION (LONG)

Text::Template
   This is a library for printing form letters! This is a library for
   playing Mad Libs!

   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.

   This is a good way to generate many kinds of output, such as error
   messages and HTML pages. Here is one way I use it: I am a freelance
   computer consultant; I write world-wide web applications. Usually I work
   with an HTML designer who designs the pages for me.

   Often these pages change a lot over the life of the project: The
   client's legal department takes several tries to get the disclaimer just
   right; the client changes the background GIF a few times; the text moves
   around, and soforth. These are all changes that are easy to make. Anyone
   proficient with the editor can go and make them. But if the page is
   embedded inside a Perl program, I don't want the designer to change it
   because you never know what they might muck up. I'd like to put the page
   in an external file instead.

   The trouble with that is that parts of the page really are generated by
   the program; it needs to fill in certani values in some places, maybe
   conditionally include some text somewhere else. The page can't just be a
   simple static file that the program reads in and prints out.

   A template has blanks, and when you print one out, the blanks are filled
   in automatically, so this is no trouble. And because the blanks are
   small and easy to recognize, it's easy to tell the page designer to stay
   away from them.

   Here's a sample template:

           Dear {$title} {$lastname},

           It has come to our attention that you are delinquent in your
           {$last_paid_month} payment.  Please remit ${$amount} immediately,
           or your patellae may be needlessly endangered.

                           Love,

                           Mark "Vizopteryx" Dominus


   Pretty simple, isn't it? Items in curly braces `{' `}' get filled in;
   everything else stays the same. Anyone can understand that. You can
   totally believe that the art director isn't going to screw this up while
   editing it.

   You can put any perl code you want into the braces, so instead of
   `{$amount}', you might want to use `{sprintf("%.2f", $amount)}', to
   print the amount rounded off to the nearest cent.

   This is good for generating form letters, HTML pages, error messages,
   and probably a lot of other things.

   Detailed documentation follows:

Version
 Version Text::Template ();
   Returns the current version of the `Text::Template' package. The current
   version is `'Text::Template 0.1 alpha $Revision: 1.2 $ $Date: 1995/12/27
   18:43:47 $''.

Constructor: `new'
     new Text::Template ( attribute => value, ... );


   This creates a new template object. You specify the source of the
   template with a set of attribute-value pairs in the arguments.

   At present, there are only two attributes. One is `type'; the other is
   `source'. `type' can be `FILEHANDLE', `FILE', or `ARRAY'. If `type' is
   `FILE', then the `source' is interpreted as the name of a file that
   contains the template to fill out. If `type' is `FILEHANDLE', then the
   `source' is interpreted as the name of a filehandle, which, when read,
   will deliver the template to fill out. A `type' of `ARRAY' means that
   the `source' is a reference to an array of strings; the template is the
   concatentation of these strings.

   Neither `type' nor `source' are optional yet.

   Here are some examples of how to call `new':

           $template = new Text::Template
                   ('type' => 'ARRAY',
                    'source' => [ "Dear {\$recipient}\n",
                                   "Up your {\$nose}.\n",
                                   "Love, {\$me}.\n" ]);

           $template = new Text::Template
                   ('type' => 'FILE',
                    'source' => '/home/mjd/src/game/youlose.tmpl');


   `new' returns a template object on success, and `undef' on failure. On
   an error, it puts an error message in the variable
   `$Text::Template::ERROR'.

`fill_in'
   Fills in a template. Returns the resulting text.

   Like `new', `fill_in' accepts a set of attribute-value pairs. At
   present, the only attributes are `package' and `broken'.

   Here's an example: Suppose that `$template' contains a template object
   that we created with this template:

           Dear {$name},
                   You owe me ${sprintf("%.2f", $amount)}.
                   Pay or I will break your {$part}.
                                   Love,
                                   Uncle Dominus.


   Here's how you might fill it in:

           $name = 'Donald';
           $amount = 141.61;
           $part = 'hyoid bone';

           $text = $template->fill_in();


   Here's another example:

           Your Royal Highness,

                   Enclosed please find a list of things I have gotten
                   for you since 1907:

                   { $list = '';
                     foreach $item (@things) {
                       $list .= " o \u$item\n";
                     }
                     $list
                   }

                           Signed,
                           Lord Chamberlain


   We want to pass in an array which will be assigned to the array
   `@things'. Here's how to do that:

           @the_things = ('ivory', 'apes', 'peacocks', );
           $template->fill_in();


   This is not very safe. The reason this isn't as safe is that if you had
   any variables named `$list' or `$item' in scope in your program at the
   point you called `fill_in', their values would be clobbered by the act
   of filling out the template.

   The next section will show how to make this safer.

 `package'

   The value of the `package' attribute names a package which contains the
   variables that should be used to fill in the template. If you omit the
   `package' attribute, `fill_in' uses the package that was active when it
   was called.

   Here's a safer version of the `Lord Chamberlain' example from the
   previous section:

           @VARS::the_things = ('ivory', 'apes', 'peacocks', );
           $template->fill_in('package' => VARS);


   This call to `fill_in' clobbers `$VARS::list' and `$VARS::item' instead
   of clobbering `$list' and `$item'. If your program didn't use anything
   in the `VARS' package, you don't have to worry that filling out the
   template is altering on your variables. =head2 broken

   If you specify a value for the `broken' attribute, it should be a
   reference to a function that `fill_in' can call if one of the little
   programs fails to evaluate.

   `fill_in' will pass an associative array to the `broken' function. The
   associative array will have at least these two members:

           text => (The full text of the little program that failed)
           error => (The text of the error message ($@) generated by eval)


   If the `broken' function returns a text string, `fill_in' will insert it
   into the template in place of the broken program, just as though the
   broken program had evaluated successfully and yielded that same string.
   If the `broken' function returns `undef', `fill_in' will stop filling in
   the template, and will immediately return undef itself.

   If you don't specify a `broken' function, you get a default one that
   inserts something like this:

           Warning

           This part of the template returned the following errors:

           syntax error at -e line 1, near "$amount;"
           Missing right bracket at -e line 1, at end of line
           Execution of -e aborted due to compilation errors.

`fill_this_in'
   Maybe it's not worth your trouble to put the template into a file; maybe
   it's a small file, and you want to leave it inline in the code. Maybe
   you don't want to have to worry about managing template objects. In that
   case, use `fill_this_in'. You give it the entire template as a string
   argument, follow with variable substitutions just like in `fill_in', and
   it gives you back the filled-in text.

   An example:

           $Q::name = 'Donald';
           $Q::amount = 141.61;
           $Q::part = 'hyoid bone';

           $text = fill_this_in Text::Template ( <<EOM, 'package' => Q);
           Dear {\$name},
           You owe me {sprintf('%.2f', \$amount)}.
           Pay or I will break your {\$part}.
                   Love,
                   Grand Vizopteryx of Irkutsk.
           EOM


Template Format
   Here's the deal with templates: Anything in braces is a little program,
   which is evaluated, and replaced with its perl value. A backslashed
   character has no special meaning, so to include a literal `{' in your
   template, use `\{', and to include a literal `\', use `\\'.

   A little program starts at an open brace and ends at the matching close
   brace. This means that your little programs can include braces and you
   don't need to worry about it. See the example below for an example of
   braces inside a little program.

   If an expression at the beginning of the template has side effects, the
   side effects carry over to the subsequent expressions. For example:

           {$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.


   Notice that after we set $x in the first little program, its value
   carries over to the second little program, and that we can set `$diff'
   and `$more' on one place and use their values again later.

   All variables are evaluated in the package you specify as an argument to
   `fill_in'. This means that if your templates don't do anything
   egregiously stupid, you don't have to worry that evaluation of the
   little programs will creep out into the rest of your program and wreck
   something. On the other hand, there's really no way to protect against a
   template that says

           { $Important::Secret::Security::Enable = 0;
             # Disable security checks in this program
           }


   or even

           { system("rm -rf /") }


   so don't go filling in templates unless you're sure you know what's in
   them. This package may eventually use Perl's `Safe' extension to fill in
   templates in a safe compartment.

Author
   Mark-Jason Dominus, Plover Systems

   `[email protected]'

Support?
   This software is version 0.1 alpha. It probably has bugs. It is
   inadequately tested. Suggestions and bug reports are always welcome.

Bugs
   This package should fill in templates in a `Safe' compartment.

   The callback function that `fill_in' calls when a template contains an
   error should be eble to return an error message to the rest of the
   program.

   `my' variables in `fill_in' are still susceptible to being clobbered by
   template evaluation. Perhaps it will be safer to make them `local'
   variables.

   Maybe there should be a utility method for emptying out a package?






--

Mark-Jason Dominus                                             [email protected]