CGI::AppToolkit::Template - Perl module to manipulate text templates
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.
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
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.
$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 a file into the template object. Called automatically be template() or CGI::AppToolkit->template().
$t = CGI::AppToolkit::Template->new(); $t->load('template.html');
Sets the template to the supplied TEXT. Called automatically be template() or CGI::AppToolkit->template().
$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
Makes the template. output and print are synonyms.
$t->make({token => 'some text', names => [{name => 'Rob'}, {name => 'David'}]});
Checks to see if the template file has been modified and reloads it if necessary.
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.
$star = $t->var('star'); @vars = $t->vars();
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.
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.
CGI::AppToolkit::Template::Filter
filter()
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.
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.
{?-- $token --?}
<else>
{?-- $token ?}
The comparison operators <, <=, >, >=, or != may be used, and you may also place an exclamation point (!) before the $token.
<
<=
>
>=
!=
!
$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?}
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.
</iftoken>
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.
value="..."
comparison="..."
not
ne
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.
as="..."
as
string
template
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).
eq
lt
le
gt
ge
<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?}
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.
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:
<option ...>
id
{?$selected-tool?}
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:
tools.tmpl
<select name="tool"> <option value="1" >Hammer <option value="2" >Name <option value="3" SELECTED>Drill <option value="4" >Saw </select>
A variable token. This will not appear in the output text, but the contents (value) can be retrieved with the var() and vars() methods.
var()
vars()
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:
make
use CGI::AppToolkit; my $t = CGI::AppToolkit->template('example.tmpl'); print $t->make({'token' => 'This is my text!'});
Given the file example.tmpl contains:
example.tmpl
<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!'} ] });
<html> <head><title>{?$title?}</title></head> <body> {?@tokens?}Some text: {?$token?} </body> </html>
<html> <head><title>All about tokens</title></head> <body> Some text: This is my text! Some text: Text Too! </body> </html>
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>
#!/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);
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.
To install CGI::AppToolkit, copy and paste the appropriate command in to your terminal.
cpanm
cpanm CGI::AppToolkit
CPAN shell
perl -MCPAN -e shell install CGI::AppToolkit
For more information on module installation, please visit the detailed CPAN module installation guide.