The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CGI::AppToolkit::Template - Perl module to manipulate text templates

DESCRIPTION

This module takes a raw complex data structure and a formatted text file and combines the two. This is useful for the generation of HTML, XML, or any other formatted text. The templating syntax is formatted for quick parsing (by human or machine) and to be usable in most GUI HTML editors without having to do a lot of backflips.

CGI::AppToolkit::Template was developed to fulfill several goals. It is similar to HTML::Template in concept and in style, but goes about it by very different means. It's goals are:

  • Simple token replacement with minimal code on the CGI or script end.

  • Simple and quick handling of complex data structures, including arrays.

  • To provide a complete seperation of HTML code and CGI code. With this module, the CGI script might not have any HTML code in it at all, and HTML will have no perl or script-like code in it at all. (The HTML designer doesn't have to know any scripting to create a very usable and powerful template.) To this end, this module also allows tokens to contain information for the CGI to read.

  • Speed. Because of this, error checking is minimal.

Methods

template([FILENAME|STRING])

Shortcut to new(-set=>"template text") or new(-file=>"filename"). If the supplied string has line endings, it's assumed to be the template text, otherwise it's assumed to be a filename. This may be called as a method or as a subroutine. It will be imported into useing namespace when requested:

  use CGI::AppToolkit::Template qw/template/;

NOTE: This module is loaded and this method is called by CGI::AppToolkit->template(), which should be used instead when using CGI::AppToolkit.

Example:

  $t = template('template.html');
  # OR
  $t = CGI::AppToolkit->template('template.html');
 
  # or to read the file in from another source manually
  open FILE, 'template.html';
  @lines = <FILE>;
  $t = template(\@lines); # must pass a ref
  # or
  $t = template(join('', @lines)); # or a single string  
new([OPTIONS])

Create a new CGI::AppToolkit::Template object. The template() method cals this method for you, or you can call it directly.

NOTE: If you are using CGI::AppToolkit, then it is highly recommended that you use it's CGI::AppToolkit->template() method instead.

OPTIONS include: load (or file), set (or text or string), and cache. load and set are shorthand for the corresponding methods. cache, if non-zero, will tell the module to cache the templates loaded from file in a package-global variable. This is very useful when running under mod_perl, for example.

Example:

  $t = CGI::AppToolkit::Template->new(-load => 'template.html');
 
  # or to read the file in from another source manually
  open FILE, 'template.html';
  @lines = <FILE>;
  $t = CGI::AppToolkit::Template->new(-text => \@lines); # must pass a ref
  # or
  $t = CGI::AppToolkit::Template->new(-text => join('', @lines)); # or a single string  
load(FILENAME)

Load a file into the template object. Called automatically be template() or CGI::AppToolkit->template().

Example:

  $t = CGI::AppToolkit::Template->new();
  $t->load('template.html');
set(TEXT)

Sets the template to the supplied TEXT. Called automatically be template() or CGI::AppToolkit->template().

Example:

  $t = CGI::AppToolkit::Template->new();

  open FILE, 'template.html';
  @lines = <FILE>;
  $t->set(\@lines); # must pass a ref
  # or
  $t->set(join('', @lines)); # or a single string  
make(HASHREF)

Makes the template. output and print are synonyms.

Example:

  $t->make({token => 'some text', names => [{name => 'Rob'}, {name => 'David'}]});
check_cache()

Checks to see if the template file has been modified and reloads it if necessary.

var(NAME)
vars()

var loads a variable tagged with NAME from the template and returns it. vars returns a list of variable names that can be passed to var.

Example:

  $star = $t->var('star');
  @vars = $t->vars();

Template Syntax

The template syntax is heirarchical and token based. Every tag has two forms: curly brace or HTML-like. All curly brace forms of tags begin with {? and end with ?}. Angle brackets <> may be used instead of curly braces {}. For example, the following are all the same:

  {? $name ?}
  <? $name ?>
  <token name="name">
  <token name>

Use of HTML-like tags or curly brace tags with angle brackets might make the template difficult to use in some GUI HTML editors.

NOTE: Tokens may be escaped with a backslash '\' ... and becuase of this, backslashes will be lost. You must escape any backslashes you want to keep in your template.

Tokens may be nested to virtually any level. The two styles, curly bace and html-like, may be mixed at will, but human readability may suffer.

Line endings may be of any OS style: Mac, UN!X, or DOS.

{? $key ?}
{? $key filter() ?}
<token name="key">
<token name="key" do="filter()">
<token key>
<token key filter()>

A simple token. Replaced with the string value of a token provided with the specified name key.

If a filter() is specified, then the named CGI::AppToolkit::Template::Filter subclass will be loaded and it's filter() function will be called, with the token's value and any parameters specified passed to it. Please see CGI::AppToolkit::Template::Filter for a list of provided filters.

NOTE: The template module's ability to parse the parameters are very rudimentary. It can only handle a comma delimited list of space-free words or single or double quoted strings. The string may have escaped quotes in them. The style of quote (single or double) makes no difference.

{?if $token --?}...{?-- $token --?}...{?-- $token ?}
{?if $token="template" --?}...{?-- $token --?}...{?-- $token ?}
{?if $token='text' --?}...{?-- $token --?}...{?-- $token ?}
{?if $token=number --?}...{?-- $token --?}...{?-- $token ?}

A decision if..else block. Checks token to be true, or compares it to the string text, the subtemplate template, or the number number, respectively, and if the test passes then the template code inside this token is appended to the output text. If there is an 'else' ({?-- $token --?} or <else>) and the test fails, the template code between the else and the end ({?-- $token ?}) will be appended to the output text.

The comparison operators <, <=, >, >=, or != may be used, and you may also place an exclamation point (!) before the $token.

  {?if $token<='a string' --?}...{?-- $token?}
  {?if !$token --?}...{?-- $token?}
  {?if !$token!='a string' --?}...{?-- $token?} <-- if token equals 'a string'

Comparison is done as a number if the value is not quoted, as a string if is single-quoted, and as a subtemplate if it is double-quoted. This is intended to be similar to the use of quotes in perl:

  <option {?if $selection = "{?$selected_item?}" --?}SELECTED{?-- $selection?}>{?$selection?}
  {?if $state != 'hidden' --?}<img src="...">{?-- $state?}
  {?if $count > 0 --?}{?$count?}{?-- $count --?}<font color="red">$count</font>{?-- $count?}
<iftoken name="token">...<else>...</iftoken>
<iftoken name="token" value="value" as="(template|string|number)" comparison="(not|eq|ne|lt|le|gt|ge)">...<else>...</iftoken>

An alternate syntax for the decision if..else block. Checks token to be true, or compares it to the value value, and if the test passes then the template code inside this token is appended to the output text. If there is an 'else' ({?-- $token --?} or <else>) and the test fails, the template code between the else and the end (</iftoken>) will be appended to the output text.

If there is no value="..." given, then the token is tested for perl 'trueness.' If the comparison="..." is given as not or ne then the 'trueness' of the token is reversed.

The value, if given, is treated as described in the as="...", or as a number if not specified. Unlike the curly brace form, the style of quoting does not matter. Possible as values are string, template, or number.

The token is compared to the value according to the value of comparison="...". Possible values are not (false), ne (not equal), eq (equal), lt (less than), le (less than or equal to), gt (greater than), or ge (greater than or equal to).

  <iftoken name="thanks">Thanks for visiting!<else>You're not welcome here! Go away.</iftoken>

You can mix token stylas as you wish, to the dismay of anyone (or any GUI HTML app) trying to read the template:

  <iftoken name="id" as="number" value="10" comparison="gt">Your id is greated than 10!{?-- $id --?}Your id <= 10.{?-- $id?}
  {?if $name --?}Hello '<token name='name'>'.<else>I don't know who you are!</iftoken>
  {?if $address --?}I know where you live!<else>I don't know your address{?-- $address?}
  <iftoken id><token id>{?-- $id?}
{? @token --?}text{?-- @token --?}text{?-- @token ?}
<repeattoken name="token">...<else>...</repeattoken>
{? @token ?}
<repeattoken name="token"/>

A repeat token. Repeats the contents of this token for each hashref contained in the arrayref provided with the name token and the results are appended to the output text. If the arrayref is empty and ther is an 'else' ({?-- $token --?} or <else>), then the template code between the else and the end (</iftoken>) will be appended to the output text.

{? @token ?}
<repeattoken name="token"/>

A repeat token, as above, except it repeats the line that it is on. The token can appear anywhere in the line.

  <select name="tool">
        <option value="{?$id?}" {?if $id="{?$selected-tool?}" --?}SELECTED{?-- $id?}>{?$name?}{?@tools?}
  </select>

In the above example, the <option ...> line will be repeated for every tool of the 'tools' array. If the id is the same as {?$selected-tool?}, then SELECTED. So, in the code we call:

  print CGI::AppToolkit->template('tools')->make(
        'tools' => [
                {'id' => 1, 'name' => 'Hammer'},
                {'id' => 2, 'name' => 'Name'},
                {'id' => 3, 'name' => 'Drill'},
                {'id' => 4, 'name' => 'Saw'},
        ],
        'selected-tool' => 3
  );

And, assuming the file is called 'tools.tmpl,' then the result should look something like:

  <select name="tool">
        <option value="1" >Hammer
        <option value="2" >Name
        <option value="3" SELECTED>Drill
        <option value="4" >Saw
  </select>
{? my $var --?}text{?-- $var ?}
{? my $var='text' ?}
<vartoken name="token">text</vartoken>
<vartoken name="token" value="text">

A variable token. This will not appear in the output text, but the contents (value) can be retrieved with the var() and vars() methods.

Data Format

The data passed to the make method corresponds to the tags in the template. Each token is a named key-value pair of a hashref. For example, the following code:

  use CGI::AppToolkit;
  my $t = CGI::AppToolkit->template('example.tmpl');
  print $t->make({'token' => 'This is my text!'});

Given the file example.tmpl contains:

  <html>
    <head><title>{?$token?}</title></head>
        <body>
        Some text: {?$token?}
        </body>
  </html>

Will print:

  <html>
    <head><title>This is my text!</title></head>
        <body>
        Some text: This is my text!
        </body>
  </html>

Complex data structures can be represented as well:

  use CGI::AppToolkit;
  my $t = CGI::AppToolkit->template('example2.tmpl');
  print $t->make({
        'title' =>'All about tokens',
        'tokens' => [
                {'token' => 'This is my text!'},
                {'token' => 'Text Too!'}
                ]
        });

Given the file example.tmpl contains:

  <html>
    <head><title>{?$title?}</title></head>
    <body>
      {?@tokens?}Some text: {?$token?}
    </body>
  </html>

Will print:

  <html>
    <head><title>All about tokens</title></head>
        <body>
      Some text: This is my text!
      Some text: Text Too!
    </body>
  </html>

SYNOPSIS

Example template:

In this example I combine the use of <?$token?> style syntax and {?$token?} style syntax.

  <html>
    <head>
      <title><?$title><title>
    <head>
      <body>
        
        <?$body?><br>
        Made by: <token name="who">
        
        <table>
          <tr>
            <td>
              Name
            </td>
            <td>
              Options
            </td>
          </tr>
  {?@repeat --?}
          <tr>
            <td>
              <token name>
            </td>
            <td>
              <a href="index.cgi?edit-id={?$id?}">Edit<?a>
            </td>
          </tr>
  {?-- @repeat?}
        </table>
      </body>
    </head>
  </html> 

  <?my $author-->
    <B><A HREF="mailto:rob@heavyhosting.net">Rob Giseburt</A></B>
  <?--$author>

Example CGI code:

  #!/bin/perl
  
  use CGI; # see the perldoc for the CGI module
  use CGI::AppToolkit;
  
  #-- Standard CGI/CGI::AppToolkit stuff --#
  $cgi = CGI->new();
  $kit = CGI::AppToolkit->new();
  $kit->connect( ... ) || die $db->errstr;
  
  # load the data from a DB
  # returns an arrayref of hashrefs
  $repeat = $kit->data('item')->fetch(-all => 1);
  
  # Place the loaded data in a page-wide data structure
  $data = {
    title => 'This is an example of CGI::AppToolkit::Template at work.',
    body => 'Select edit from one of the options below:',
    repeat => $repeat
  };
  
  # print the CGI header
  print $cgi->header();
  
  #-- CGI::AppToolkit::Template stuff --#
  
  $template = $kit->template('example.tmpl');
  
  # load the 'author' HTML from the template
  $author = $template->var('author');
  # place it into the data
  $data->{'who'} = $author;

  # output the results of the data inserted into the template
  print $template->output($data);

AUTHOR

Copyright 2002 Robert Giseburt (rob@heavyhosting.net). All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Please visit http://www.heavyhosting.net/AppToolkit/ for complete documentation.