home *** CD-ROM | disk | FTP | other *** search
-
- <HTML>
- <HEAD>
- <TITLE>HTML::Template - Perl module to use HTML Templates from CGI scripts</TITLE>
- <LINK REL="stylesheet" HREF="../../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> HTML::Template - Perl module to use HTML Templates from CGI scripts</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
-
- <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <LI><A HREF="#motivation">MOTIVATION</A></LI>
- <LI><A HREF="#the tags">The Tags</A></LI>
- <UL>
-
- <LI><A HREF="#<tmpl_var escape=1 name=parameter_name>"><TMPL_VAR ?ESCAPE=1? NAME=``PARAMETER_NAME''></A></LI>
- <LI><A HREF="#<tmpl_loop name=loop_name> </tmpl_loop>"><TMPL_LOOP NAME=``LOOP_NAME''> </TMPL_LOOP></A></LI>
- <LI><A HREF="#<tmpl_include name=filename.tmpl>"><TMPL_INCLUDE NAME=``filename.tmpl''></A></LI>
- <LI><A HREF="#<tmpl_if name=control_parameter_name> </tmpl_if>"><TMPL_IF NAME=``CONTROL_PARAMETER_NAME''> </TMPL_IF></A></LI>
- <LI><A HREF="#<tmpl_else>"><TMPL_ELSE></A></LI>
- <LI><A HREF="#<tmpl_unless name=control_parameter_name> </tmpl_unless>"><TMPL_UNLESS NAME=``CONTROL_PARAMETER_NAME''> </TMPL_UNLESS></A></LI>
- </UL>
-
- <LI><A HREF="#methods">Methods</A></LI>
- <UL>
-
- <LI><A HREF="#new()"><CODE>new()</CODE></A></LI>
- <LI><A HREF="#param">param</A></LI>
- <LI><A HREF="#clear_params()"><CODE>clear_params()</CODE></A></LI>
- <LI><A HREF="#output()"><CODE>output()</CODE></A></LI>
- </UL>
-
- <LI><A HREF="#frequently asked questions">FREQUENTLY ASKED QUESTIONS</A></LI>
- <LI><A HREF="#bugs">BUGS</A></LI>
- <LI><A HREF="#credits">CREDITS</A></LI>
- <LI><A HREF="#public cvs server">PUBLIC CVS SERVER</A></LI>
- <LI><A HREF="#author">AUTHOR</A></LI>
- <LI><A HREF="#license">LICENSE</A></LI>
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>HTML::Template - Perl module to use HTML Templates from CGI scripts</P>
- <P>
- <HR>
- <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
- <UL>
- <LI>Linux</LI>
- <LI>Solaris</LI>
- <LI>Windows</LI>
- </UL>
- <HR>
- <H1><A NAME="synopsis">SYNOPSIS</A></H1>
- <P>First you make a template - this is just a normal HTML file with a few
- extra tags, the simplest being <TMPL_VAR></P>
- <P>For example, test.tmpl:</P>
- <PRE>
- <HTML>
- <HEAD><TITLE>Test Template</TITLE>
- <BODY>
- My Home Directory is <TMPL_VAR NAME=HOME>
- <P>
- My Path is set to <TMPL_VAR NAME=PATH>
- </BODY>
- </HTML></PRE>
- <P>Now create a small CGI program:</P>
- <PRE>
- use HTML::Template;</PRE>
- <PRE>
- # open the html template
- my $template = HTML::Template->new(filename => 'test.tmpl');</PRE>
- <PRE>
- # fill in some parameters
- $template->param(
- HOME => $ENV{HOME},
- PATH => $ENV{PATH},
- );</PRE>
- <PRE>
- # send the obligatory Content-Type
- print "Content-Type: text/html\n\n";</PRE>
- <PRE>
- # print the template
- print $template->output;</PRE>
- <P>If all is well in the universe this should show something like this in
- your browser when visiting the CGI:</P>
- <P>My Home Directory is /home/some/directory
- My Path is set to /bin;/usr/bin</P>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P>This module attempts to make using HTML templates simple and natural. It
- extends standard HTML with a few new HTML-esque tags - <TMPL_VAR>,
- <TMPL_LOOP>, <TMPL_INCLUDE>, <TMPL_IF> and <TMPL_ELSE>. The file
- written with HTML and these new tags is called a template. It is
- usually saved separate from your script - possibly even created by
- someone else! Using this module you fill in the values for the
- variables, loops and branches declared in the template. This allows
- you to separate design - the HTML - from the data, which you generate
- in the Perl script.</P>
- <P>This module is licensed under the GPL. See the LICENSE section
- below for more details.</P>
- <P>
- <HR>
- <H1><A NAME="motivation">MOTIVATION</A></H1>
- <P>It is true that there are a number of packages out there to do HTML
- templates. On the one hand you have things like HTML::Embperl which
- allows you freely mix Perl with HTML. On the other hand lie
- home-grown variable substitution solutions. Hopefully the module can
- find a place between the two.</P>
- <P>One advantage of this module over a full HTML::Embperl-esque solution
- is that it enforces an important divide - design and programming. By
- limiting the programmer to just using simple variables and loops in
- the HTML, the template remains accessible to designers and other
- non-perl people. The use of HTML-esque syntax goes further to make
- the format understandable to others. In the future this similarity
- could be used to extend existing HTML editors/analyzers to support
- HTML::Template.</P>
- <P>An advantage of this module over home-grown tag-replacement schemes is
- the support for loops. In my work I am often called on to produce
- tables of data in html. Producing them using simplistic HTML
- templates results in CGIs containing lots of HTML since the HTML
- itself cannot represent loops. The introduction of loop statements in
- the HTML simplifies this situation considerably. The designer can
- layout a single row and the programmer can fill it in as many times as
- necessary - all they must agree on is the parameter names.</P>
- <P>For all that, I think the best thing about this module is that it does
- just one thing and it does it quickly and carefully. It doesn't try
- to replace Perl and HTML, it just augments them to interact a little
- better. And it's pretty fast.</P>
- <P>
- <HR>
- <H1><A NAME="the tags">The Tags</A></H1>
- <P>Note: even though these tags look like HTML they are a little
- different in a couple of ways. First, they must appear entirely on
- one line. Second, they're allowed to ``break the rules''. Something
- like:</P>
- <PRE>
- <IMG SRC="<TMPL_VAR NAME=IMAGE_SRC>"></PRE>
- <P>is not really valid HTML, but it is a perfectly valid use and will
- work as planned.</P>
- <P>The ``NAME='' in the tag is optional, although for extensibility's sake I
- recommend using it. Example - ``<TMPL_LOOP LOOP_NAME>'' is acceptable.</P>
- <P>If you're a fanatic about valid HTML and would like your templates
- to conform to valid HTML syntax, you may optionally type template tags
- in the form of HTML comments. This may be of use to HTML authors who
- would like to validate their templates' HTML syntax prior to
- HTML::Template processing, or who use DTD-savvy editing tools.</P>
- <PRE>
- <!-- TMPL_VAR NAME=PARAM1 --></PRE>
- <P>In order to realize a dramatic savings in bandwidth, the standard
- (non-comment) tags will be used throughout the rest of this
- documentation.</P>
- <P>
- <H2><A NAME="<tmpl_var escape=1 name=parameter_name>"><TMPL_VAR ?ESCAPE=1? NAME=``PARAMETER_NAME''></A></H2>
- <P>The <TMPL_VAR> tag is very simple. For each <TMPL_VAR> tag in the
- template you call $template->param(PARAMETER_NAME => ``VALUE''). When
- the template is output the <TMPL_VAR> is replaced with the VALUE text
- you specified. If you don't set a parameter it just gets skipped in
- the output.</P>
- <P>Optionally you can use the ``ESCAPE=HTML'' option in the tag to indicate
- that you want the value to be HTML-escaped before being returned from
- output (the old ESCAPE=1 syntax is still supported). This means that
- the ``, <, >, and & characters get translated into ", <, >
- and & respectively. This is useful when you want to use a
- TMPL_VAR in a context where those characters would cause trouble.
- Example:</P>
- <PRE>
- <INPUT NAME=param TYPE=TEXT VALUE="<TMPL_VAR NAME="param">"></PRE>
- <P>If you called <CODE>param()</CODE> with a value like sam``my you'll get in trouble
- with HTML's idea of a double-quote. On the other hand, if you use
- ESCAPE=HTML, like this:</P>
- <PRE>
- <INPUT NAME=param TYPE=TEXT VALUE="<TMPL_VAR ESCAPE=HTML NAME="param">"></PRE>
- <P>You'll get what you wanted no matter what value happens to be passed in for
- param. You can also write ESCAPE=``HTML'', ESCAPE='HTML' and ESCAPE='1'.
- Substitute a 0 for the HTML and you turn off escaping, which is the default
- anyway.</P>
- <P>There is also the ``ESCAPE=URL'' option which may be used for VARs that
- populate a URL. It will do URL escaping, like replacing ' ' with '+'
- and '/' with '%2F'.</P>
- <P>
- <H2><A NAME="<tmpl_loop name=loop_name> </tmpl_loop>"><TMPL_LOOP NAME=``LOOP_NAME''> </TMPL_LOOP></A></H2>
- <P>The <TMPL_LOOP> tag is a bit more complicated. The <TMPL_LOOP> tag
- allows you to delimit a section of text and give it a name. Inside
- the <TMPL_LOOP> you place <TMPL_VAR>s. Now you pass to <CODE>param()</CODE> a list
- (an array ref) of parameter assignments (hash refs). The loop
- iterates over this list and produces output from the text block for
- each pass. Unset parameters are skipped. Here's an example:</P>
- <PRE>
- In the template:</PRE>
- <PRE>
- <TMPL_LOOP NAME=EMPLOYEE_INFO>
- Name: <TMPL_VAR NAME=NAME> <P>
- Job: <TMPL_VAR NAME=JOB> <P>
- <P>
- </TMPL_LOOP></PRE>
- <PRE>
- In the script:</PRE>
- <PRE>
- $template->param(EMPLOYEE_INFO => [
- { name => 'Sam', job => 'programmer' },
- { name => 'Steve', job => 'soda jerk' },
- ]
- );
- print $template->output();</PRE>
- <P></P>
- <PRE>
-
- The output:</PRE>
- <PRE>
- Name: Sam <P>
- Job: programmer <P>
- <P>
- Name: Steve <P>
- Job: soda jerk <P>
- <P></PRE>
- <P>As you can see above the <TMPL_LOOP> takes a list of variable
- assignments and then iterates over the loop body producing output.</P>
- <P>Often you'll want to generate a <TMPL_LOOP>'s contents
- programmatically. Here's an example of how this can be done (many
- other ways are possible!):</P>
- <PRE>
- # a couple of arrays of data to put in a loop:
- my @words = qw(I Am Cool);
- my @numbers = qw(1 2 3);</PRE>
- <PRE>
- my @loop_data = (); # initialize an array to hold your loop</PRE>
- <PRE>
- while (@words and @numbers) {
- my %row_data; # get a fresh hash for the row data</PRE>
- <PRE>
- # fill in this row
- $row_data{WORD} = shift @words;
- $row_data{NUMBER} = shift @numbers;
- </PRE>
- <PRE>
-
- # the crucial step - push a reference to this row into the loop!
- push(@loop_data, \%row_data);
- }</PRE>
- <PRE>
- # finally, assign the loop data to the loop param, again with a
- # reference:
- $template->param(THIS_LOOP => \@loop_data);</PRE>
- <P>The above example would work with a template like:</P>
- <PRE>
- <TMPL_LOOP NAME="THIS_LOOP">
- Word: <TMPL_VAR NAME="WORD"><BR>
- Number: <TMPL_VAR NAME="NUMBER"><P>
- </TMPL_LOOP></PRE>
- <P>It would produce output like:</P>
- <PRE>
- Word: I
- Number: 1</PRE>
- <PRE>
- Word: Am
- Number: 2</PRE>
- <PRE>
- Word: Cool
- Number: 3</PRE>
- <P><TMPL_LOOP>s within <TMPL_LOOP>s are fine and work as you would
- expect. If the syntax for the <CODE>param()</CODE> call has you stumped, here's an
- example of a param call with one nested loop:</P>
- <PRE>
- $template->param('ROW',[
- { name => 'Bobby',
- nicknames => [
- { name => 'the big bad wolf' },
- { name => 'He-Man' },
- ],
- },
- ],
- );</PRE>
- <P>Basically, each <TMPL_LOOP> gets an array reference. Inside the array
- are any number of hash references. These hashes contain the
- name=>value pairs for a single pass over the loop template.</P>
- <P>Inside a <TMPL_LOOP>, the only variables that are usable are the ones
- from the <TMPL_LOOP>. The variables in the outer blocks are not
- visible within a template loop. For the computer-science geeks among
- you, a <TMPL_LOOP> introduces a new scope much like a perl subroutine
- call. Unlike perl, there are no global variables in the templates.</P>
- <P>
- <H2><A NAME="<tmpl_include name=filename.tmpl>"><TMPL_INCLUDE NAME=``filename.tmpl''></A></H2>
- <P>This tag includes a template directly into the current template at the
- point where the tag is found. The included template contents are used
- exactly as if its contents were physically included in the master
- template.</P>
- <P>The file specified can be a full path - beginning with a '/'. If it
- isn't a full path, the path to the enclosing file is tried first.
- After that the path in the environment variable HTML_TEMPLATE_ROOT is
- tried next, if it exists. Next, the ``path'' <CODE>new()</CODE> option is consulted.
- As a final attempt, the filename is passed to <A HREF="../../../lib/Pod/perlfunc.html#item_open"><CODE>open()</CODE></A> directly. See
- below for more information on HTML_TEMPLATE_ROOT and the ``path'' option
- to new().</P>
- <P>As a protection against infinitly recursive includes, an arbitary
- limit of 10 levels deep is imposed. You can alter this limit with the
- ``max_includes'' option. See the entry for the ``max_includes'' option
- below for more details.</P>
- <P>
- <H2><A NAME="<tmpl_if name=control_parameter_name> </tmpl_if>"><TMPL_IF NAME=``CONTROL_PARAMETER_NAME''> </TMPL_IF></A></H2>
- <P>The <TMPL_IF> tag allows you to include or not include a block of the
- template based on the value of a given parameter name. If the
- parameter is given a value that is true for Perl - like '1' - then the
- block is included in the output. If it is not defined, or given a
- false value - like '0' - then it is skipped. The parameters are
- specified the same way as with TMPL_VAR.</P>
- <P>Example Template:</P>
- <PRE>
- <TMPL_IF NAME="BOOL">
- Some text that only gets displayed if BOOL is true!
- </TMPL_IF></PRE>
- <P>Now if you call $template->param(BOOL => 1) then the above block will
- be included by output.</P>
- <P><TMPL_IF> </TMPL_IF> blocks can include any valid HTML::Template
- construct - VARs and LOOPs and other IF/ELSE blocks. Note, however,
- that intersecting a <TMPL_IF> and a <TMPL_LOOP> is invalid.</P>
- <PRE>
- Not going to work:
- <TMPL_IF BOOL>
- <TMPL_LOOP SOME_LOOP>
- </TMPL_IF>
- </TMPL_LOOP></PRE>
- <P>If the name of a TMPL_LOOP is used in a TMPL_IF, the IF block will
- output if the loop has at least one row. Example:</P>
- <PRE>
- <TMPL_IF LOOP_ONE>
- This will output if the loop is not empty.
- </TMPL_IF></PRE>
- <PRE>
- <TMPL_LOOP LOOP_ONE>
- ....
- </TMPL_LOOP></PRE>
- <P>WARNING: Much of the benefit of HTML::Template is in decoupling your
- Perl and HTML. If you introduce numerous cases where you have
- TMPL_IFs and matching Perl if()s, you will create a maintenance
- problem in keeping the two synchronized. I suggest you adopt the
- practice of only using TMPL_IF if you can do so without requiring a
- matching <CODE>if()</CODE> in your Perl code.</P>
- <P>
- <H2><A NAME="<tmpl_else>"><TMPL_ELSE></A></H2>
- <P>You can include an alternate block in your TMPL_IF block by using
- TMPL_ELSE. NOTE: You still end the block with </TMPL_IF>, not
- </TMPL_ELSE>!
- </P>
- <PRE>
-
- Example:</PRE>
- <PRE>
- <TMPL_IF BOOL>
- Some text that is included only if BOOL is true
- <TMPL_ELSE>
- Some text that is included only if BOOL is false
- </TMPL_IF></PRE>
- <P>
- <H2><A NAME="<tmpl_unless name=control_parameter_name> </tmpl_unless>"><TMPL_UNLESS NAME=``CONTROL_PARAMETER_NAME''> </TMPL_UNLESS></A></H2>
- <P>This tag is the opposite of <TMPL_IF>. The block is output if the
- CONTROL_PARAMETER is set false or not defined. You can use
- <TMPL_ELSE> with <TMPL_UNLESS> just as you can with <TMPL_IF>.</P>
- <PRE>
- Example:</PRE>
- <PRE>
- <TMPL_UNLESS BOOL>
- Some text that is output only if BOOL is FALSE.
- <TMPL_ELSE>
- Some text that is output only if BOOL is TRUE.
- </TMPL_UNLESS></PRE>
- <P>If the name of a TMPL_LOOP is used in a TMPL_UNLESS, the UNLESS block
- output if the loop has zero rows.</P>
- <PRE>
- <TMPL_UNLESS LOOP_ONE>
- This will output if the loop is empty.
- </TMPL_UNLESS>
- </PRE>
- <PRE>
-
- <TMPL_LOOP LOOP_ONE>
- ....
- </TMPL_LOOP></PRE>
- <P>
- <HR>
- <H1><A NAME="methods">Methods</A></H1>
- <P>
- <H2><A NAME="new()"><CODE>new()</CODE></A></H2>
- <P>Call <CODE>new()</CODE> to create a new Template object:</P>
- <PRE>
- my $template = HTML::Template->new( filename => 'file.tmpl',
- option => 'value'
- );</PRE>
- <P>You must call <CODE>new()</CODE> with at least one name => value pair specifying how
- to access the template text. You can use ``filename => 'file.tmpl''' to
- specify a filename to be opened as the template. Alternately you can
- use:</P>
- <PRE>
- my $t = HTML::Template->new( scalarref => $ref_to_template_text,
- option => 'value'
- );</PRE>
- <P>and</P>
- <PRE>
- my $t = HTML::Template->new( arrayref => $ref_to_array_of_lines ,
- option => 'value'
- );</PRE>
- <P>These initialize the template from in-memory resources. In almost
- every case you'll want to use the filename parameter. If you're
- worried about all the disk access from reading a template file just
- use mod_perl and the cache option detailed below.</P>
- <P>The three <CODE>new()</CODE> calling methods can also be accessed as below, if you
- prefer.</P>
- <PRE>
- my $t = HTML::Template->new_file('file.tmpl', option => 'value');</PRE>
- <PRE>
- my $t = HTML::Template->new_scalar_ref($ref_to_template_text,
- option => 'value');</PRE>
- <PRE>
- my $t = HTML::Template->new_array_ref($ref_to_array_of_lines,
- option => 'value');</PRE>
- <P>And as a final option, for those that might prefer it, you can call new as:</P>
- <PRE>
- my $t = HTML::Template->new(type => 'filename',
- source => 'file.tmpl');</PRE>
- <P>Which works for all three of the source types.</P>
- <P>If the environment variable HTML_TEMPLATE_ROOT is set and your
- filename doesn't begin with /, then the path will be relative to the
- value of $HTML_TEMPLATE_ROOT. Example - if the environment variable
- HTML_TEMPLATE_ROOT is set to ``/home/sam'' and I call
- HTML::Template-><CODE>new()</CODE> with filename set to ``sam.tmpl'', the
- HTML::Template will try to open ``/home/sam/sam.tmpl'' to access the
- template file. You can also affect the search path for files with the
- ``path'' option to <CODE>new()</CODE> - see below for more information.</P>
- <P>You can modify the Template object's behavior with new. These options
- are available:</P>
- <UL>
- <LI>
- die_on_bad_params - if set to 0 the module will let you call
- $template->param(param_name => 'value') even if 'param_name' doesn't
- exist in the template body. Defaults to 1.
- <P></P>
- <LI>
- strict - if set to 0 the module will allow things that look like they might be TMPL_* tags to get by without dieing. Example:
- <PRE>
- <TMPL_HUH NAME=ZUH></PRE>
- <P>Would normally cause an error, but if you call new with strict => 0,
- HTML::Template will ignore it. Defaults to 1.</P>
- <P></P>
- <LI>
- cache - if set to 1 the module will cache in memory the parsed
- templates based on the filename parameter and modification date of the
- file. This only applies to templates opened with the filename
- parameter specified, not scalarref or arrayref templates. Caching
- also looks at the modification times of any files included using
- <TMPL_INCLUDE> tags, but again, only if the template is opened with
- filename parameter.
- <P>This is mainly of use in a persistent environment like
- Apache/mod_perl. It has absolutely no benefit in a normal CGI
- environment since the script is unloaded from memory after every
- request. For a cache that does work for normal CGIs see the
- 'shared_cache' option below.</P>
- <P>Note that different <CODE>new()</CODE> parameter settings do not cause a cache
- refresh, only a change in the modification time of the template will
- trigger a cache refresh. For most usages this is fine. My simplistic
- testing shows that using cache yields a 90% performance increase under
- mod_perl. Cache defaults to 0.</P>
- <P></P>
- <LI>
- shared_cache - if set to 1 the module will store its cache in shared
- memory using the IPC::SharedCache module (available from CPAN). The
- effect of this will be to maintain a single shared copy of each parsed
- template for all instances of HTML::Template to use. This can be a
- significant reduction in memory usage in a multiple server
- environment. As an example, on one of our systems we use 4MB of
- template cache and maintain 25 httpd processes - shared_cache results
- in saving almost 100MB! Of course, some reduction in speed versus
- normal caching is to be expected. Another difference between normal
- caching and shared_cache is that shared_cache will work in a CGI
- environment - normal caching is only useful in a persistent
- environment like Apache/mod_perl.
- <P>By default HTML::Template uses the IPC key 'TMPL' as a shared root
- segment (0x4c504d54 in hex), but this can be changed by setting the
- 'ipc_key' <CODE>new()</CODE> parameter to another 4-character or integer key.
- Other options can be used to affect the shared memory cache correspond
- to IPC::SharedCache options - ipc_mode, ipc_segment_size and
- ipc_max_size. See <A HREF="../../../IPC/SharedCache.html">the IPC::SharedCache manpage</A> for a description of how these
- work - in most cases you shouldn't need to change them from the
- defaults.</P>
- <P>For more information about the shared memory cache system used by
- HTML::Template see <A HREF="../../../IPC/SharedCache.html">the IPC::SharedCache manpage</A>.</P>
- <P></P>
- <LI>
- double_cache - if set to 1 the module will use a combination of
- shared_cache and normal cache mode for the best possible caching. Of
- course, it also uses the most memory of all the cache modes. All the
- same ipc_* options that work with shared_cache apply to double_cache
- as well. By default double_cache is off.
- <P></P>
- <LI>
- blind_cache - if set to 1 the module behaves exactly as with normal
- caching but does not check to see if the file has changed on each
- request. This option should be used with caution, but could be of use
- on high-load servers. My tests show blind_cache performing only 1 to
- 2 percent faster than cache under mod_perl.
- <P>NOTE: Combining this option with shared_cache can result in stale
- templates stuck permanently in shared memory!</P>
- <P></P>
- <LI>
- associate - this option allows you to inherit the parameter values
- from other objects. The only requirement for the other object is that
- it have a <CODE>param()</CODE> method that works like HTML::Template's param(). A
- good candidate would be a CGI.pm query object. Example:
- <PRE>
- my $query = new CGI;
- my $template = HTML::Template->new(filename => 'template.tmpl',
- associate => $query);</PRE>
- <P>Now, $template-><CODE>output()</CODE> will act as though</P>
- <PRE>
- $template->param('FormField', $cgi->param('FormField'));</PRE>
- <P>had been specified for each key/value pair that would be provided by
- the $cgi-><CODE>param()</CODE> method. Parameters you set directly take precedence
- over associated parameters.</P>
- <P>You can specify multiple objects to associate by passing an anonymous
- array to the associate option. They are searched for parameters in
- the order they appear:</P>
- <PRE>
- my $template = HTML::Template->new(filename => 'template.tmpl',
- associate => [$query, $other_obj]);</PRE>
- <P>The old <CODE>associateCGI()</CODE> call is still supported, but should be
- considered obsolete.</P>
- <P>NOTE: The parameter names are matched in a case-insensitve manner. If
- you have two parameters in a CGI object like 'NAME' and 'Name' one
- will be chosen randomly by associate.</P>
- <P></P>
- <LI>
- loop_context_vars - when this parameter is set to true (it is false by
- default) three loop context variables are made available inside a
- loop: __FIRST__, __LAST__ and __INNER__. They can be used with
- <TMPL_IF>, <TMPL_UNLESS> and <TMPL_ELSE> to control how a loop is
- output. Example:
- <PRE>
- <TMPL_LOOP NAME="FOO">
- <TMPL_IF NAME="__FIRST__">
- This only outputs on the first pass.
- </TMPL_IF></PRE>
- <PRE>
- <TMPL_IF NAME="__INNER__">
- This outputs on passes that are neither first nor last.
- </TMPL_IF></PRE>
- <PRE>
- <TMPL_IF NAME="__LAST__">
- This only outputs on the last pass.
- <TMPL_IF>
- </TMPL_LOOP></PRE>
- <P>One use of this feature is to provide a ``separator'' similar in effect
- to the perl function join(). Example:</P>
- <PRE>
- <TMPL_LOOP FRUIT>
- <TMPL_IF __LAST__> and </TMPL_IF>
- <TMPL_VAR KIND><TMPL_UNLESS __LAST__>, <TMPL_ELSE>.</TMPL_UNLESS>
- </TMPL_LOOP></PRE>
- <P>Would output (in a browser) something like:</P>
- <PRE>
- Apples, Oranges, Brains, Toes, and Kiwi.</PRE>
- <P>Given an appropriate <CODE>param()</CODE> call, of course. NOTE: A loop with only
- a single pass will get both __FIRST__ and __LAST__ set to true, but
- not __INNER__.</P>
- <P></P>
- <LI>
- path - you can set this variable with a list of paths to search for
- files specified with the ``filename'' option to <CODE>new()</CODE> and for files
- included with the <TMPL_INCLUDE> tag. This list is only consulted
- when the filename is relative - i.e. does not begin with a '/'. The
- HTML_TEMPLATE_ROOT environment variable is always tried first if it
- exists. In the case of a <TMPL_INCLUDE> file, the path to the
- including file is also tried before path is consulted.
- <P>Example:</P>
- <PRE>
- my $template = HTML::Template->new( filename => 'file.tmpl',
- path => [ '/path/to/templates',
- '/alternate/path'
- ]
- );</PRE>
- <P></P>
- <LI>
- max_includes - set this variable to determine the maximum depth that
- includes can reach. Set to 10 by default. Including files to a depth
- greater than this value causes an error message to be displayed. Set
- to 0 to disable this protection.
- <P></P>
- <LI>
- vanguard_compatibility_mode - if set to 1 the module will expect to
- see <TMPL_VAR>s that look like %NAME% in addition to the standard
- syntax. Also sets die_on_bad_params => 0. If you're not at Vanguard
- Media trying to use an old format template don't worry about this one.
- Defaults to 0.
- <P></P>
- <LI>
- debug - if set to 1 the module will write random debugging information
- to STDERR. Defaults to 0.
- <P></P>
- <LI>
- stack_debug - if set to 1 the module will use Data::Dumper to print
- out the contents of the parse_stack to STDERR. Defaults to 0.
- <P></P>
- <LI>
- cache_debug - if set to 1 the module will send information on cache
- loads, hits and misses to STDERR. Defaults to 0.
- <P></P>
- <LI>
- shared_cache_debug - if set to 1 the module will turn on the debug
- option in IPC::SharedCache - see <A HREF="../../../IPC/SharedCache.html">the IPC::SharedCache manpage</A> for
- details. Defaults to 0.
- <P></P>
- <LI>
- memory_debug - if set to 1 the module will send information on cache
- memory usage to STDERR. Requires the GTop module. Defaults to 0.
- <P></P></UL>
- <P>
- <H2><A NAME="param">param</A></H2>
- <P><CODE>param()</CODE> can be called in a number of ways</P>
- <P>1) To return a list of parameters in the template :</P>
- <PRE>
- my @parameter_names = $self->param();</PRE>
- <P>2) To return the value set to a param :</P>
- <PRE>
- my $value = $self->param('PARAM');</PRE>
- <P>3) To set the value of a parameter :</P>
- <PRE>
- # For simple TMPL_VARs:
- $self->param(PARAM => 'value');</PRE>
- <PRE>
- # with a subroutine reference that gets called to get the value of
- # the scalar.
- $self->param(PARAM => sub { return 'value' });</PRE>
- <PRE>
- # And TMPL_LOOPs:
- $self->param(LOOP_PARAM =>
- [
- { PARAM => VALUE_FOR_FIRST_PASS, ... },
- { PARAM => VALUE_FOR_SECOND_PASS, ... }
- ...
- ]
- );</PRE>
- <P>4) To set the value of a a number of parameters :</P>
- <PRE>
- # For simple TMPL_VARs:
- $self->param(PARAM => 'value',
- PARAM2 => 'value'
- );</PRE>
- <PRE>
- # And with some TMPL_LOOPs:
- $self->param(PARAM => 'value',
- PARAM2 => 'value',
- LOOP_PARAM =>
- [
- { PARAM => VALUE_FOR_FIRST_PASS, ... },
- { PARAM => VALUE_FOR_SECOND_PASS, ... }
- ...
- ],
- ANOTHER_LOOP_PARAM =>
- [
- { PARAM => VALUE_FOR_FIRST_PASS, ... },
- { PARAM => VALUE_FOR_SECOND_PASS, ... }
- ...
- ]
- );</PRE>
- <P>5) To set the value of a a number of parameters using a hash-ref :</P>
- <PRE>
- $self->param(
- {
- PARAM => 'value',
- PARAM2 => 'value',
- LOOP_PARAM =>
- [
- { PARAM => VALUE_FOR_FIRST_PASS, ... },
- { PARAM => VALUE_FOR_SECOND_PASS, ... }
- ...
- ],
- ANOTHER_LOOP_PARAM =>
- [
- { PARAM => VALUE_FOR_FIRST_PASS, ... },
- { PARAM => VALUE_FOR_SECOND_PASS, ... }
- ...
- ]
- }
- );</PRE>
- <P>
- <H2><A NAME="clear_params()"><CODE>clear_params()</CODE></A></H2>
- <P>Sets all the parameters to undef. Useful internally, if nowhere else!</P>
- <P>
- <H2><A NAME="output()"><CODE>output()</CODE></A></H2>
- <P><CODE>output()</CODE> returns the final result of the template. In most situations you'll want to print this, like:</P>
- <PRE>
- print $template->output();</PRE>
- <P>When output is called each occurrence of <TMPL_VAR NAME=name> is
- replaced with the value assigned to ``name'' via param(). If a named
- parameter is unset it is simply replaced with ''. <TMPL_LOOPS> are
- evaluated once per parameter set, accumlating output on each pass.</P>
- <P>Calling <CODE>output()</CODE> is guaranteed not to change the state of the
- Template object, in case you were wondering. This property is mostly
- important for the internal implementation of loops.</P>
- <P>
- <HR>
- <H1><A NAME="frequently asked questions">FREQUENTLY ASKED QUESTIONS</A></H1>
- <P>In the interest of greater understanding I've started a FAQ section of
- the perldocs. Please look in here before you send me email.</P>
- <P>1) Is there a place to go to discuss HTML::Template and/or get help?</P>
- <P>There's a mailing-list for HTML::Template at <A HREF="mailto:htmltmpl@lists.vm.com.">htmltmpl@lists.vm.com.</A>
- Send a blank message to <A HREF="mailto:htmltmpl-subscribe@lists.vm.com">htmltmpl-subscribe@lists.vm.com</A> to join!</P>
- <P>2) I want support for <TMPL_XXX>! How about it?</P>
- <P>Maybe. I definitely encourage people to discuss their ideas for
- HTML::Template on the mailing list. Please be ready to explain to me
- how the new tag fits in with HTML::Template's mission to provide a
- fast, lightweight system for using HTML templates.</P>
- <P>NOTE: Offering to program said addition and provide it in the form of
- a patch to the most recent version of HTML::Template will definitely
- have a softening effect on potential opponents!</P>
- <P>3) I found a bug, can you fix it?</P>
- <P>That depends. Did you send me the VERSION of HTML::Template, a test
- script and a test template? If so, then almost certainly.</P>
- <P>If you're feeling really adventurous, HTML::Template has a publically
- available CVS server. See below for more information in the PUBLIC
- CVS SERVER section.</P>
- <P>4) <TMPL_VAR>s from the main template aren't working inside a <TMPL_LOOP>! Why?</P>
- <P>This is the intended behavior. <TMPL_LOOP> introduces a separate
- scope for <TMPL_VAR>s much like a subroutine call in Perl introduces a
- separate scope for ``my'' variables. If you need to have a variable
- from the main template work inside a loop you'll need to manually
- provide the value for each iteration of the loop.</P>
- <P>5) Why do you use /[Tt]/ instead of /t/i? It's so ugly!</P>
- <P>Simple - the case-insensitive match switch is very inefficient.
- According to _Mastering_Regular_Expressions_ from O'Reilly Press,
- /[Tt]/ is faster and more space efficient than /t/i - by as much as
- double against long strings. //i essentially does a <A HREF="../../../lib/Pod/perlfunc.html#item_lc"><CODE>lc()</CODE></A> on the
- string and keeps a temporary copy in memory.</P>
- <P>When this changes, and it is in the 5.6 development series, I will
- gladly use //i. Believe me, I realize [Tt] is hideously ugly.</P>
- <P>6) How can I pre-load my templates using cache-mode and mod_perl?</P>
- <P>Add something like this to your startup.pl:</P>
- <PRE>
- use HTML::Template;
- use File::Find;</PRE>
- <PRE>
- print STDERR "Pre-loading HTML Templates...\n";
- find(
- sub {
- return unless /\.tmpl$/;
- HTML::Template->new(
- filename => "$File::Find::dir/$_",
- cache => 1,
- );
- },
- '/path/to/templates',
- '/another/path/to/templates/'
- );</PRE>
- <P>Note that you'll need to modify the ``return unless'' line to specify
- the extension you use for your template files - I use .tmpl, as you
- can see. You'll also need to specify the path to your template files.</P>
- <P>One potential problem: the ``/path/to/templates/'' must be EXACTLY the
- same path you use when you call HTML::Template->new(). Otherwise the
- cache won't know they're the same file and will load a new copy -
- instead getting a speed increase, you'll double your memory usage. To
- find out if this is happening set cache_debug => 1 in your application
- code and look for ``CACHE MISS'' messages in the logs.</P>
- <P>7) What characters are allowed in TMPL_* NAMEs?</P>
- <P>Numbers, letters, '.', '/', '+', '-' and '_'.</P>
- <P>
- <HR>
- <H1><A NAME="bugs">BUGS</A></H1>
- <P>I am aware of no bugs - if you find one, join the mailing list and
- tell us about it (<A HREF="mailto:htmltmpl@lists.vm.com">htmltmpl@lists.vm.com</A>) You can join the
- HTML::Template mailing-list by sending a blank email to
- <A HREF="mailto:htmltmpl-subscribe@lists.vm.com.">htmltmpl-subscribe@lists.vm.com.</A> Of course, you can still email me
- directly (<A HREF="mailto:sam@tregar.com">sam@tregar.com</A>) with bugs, but I reserve the right to
- forward said bug reports to the mailing list.</P>
- <P>When submitting bug reports, be sure to include full details,
- including the VERSION of the module, a test script and a test template
- demonstrating the problem!</P>
- <P>If you're feeling really adventurous, HTML::Template has a publically
- available CVS server. See below for more information in the PUBLIC
- CVS SERVER section.</P>
- <P>
- <HR>
- <H1><A NAME="credits">CREDITS</A></H1>
- <P>This module was the brain child of my boss, Jesse Erlbaum
- (<A HREF="mailto:jesse@vm.com">jesse@vm.com</A>) here at Vanguard Media. The most original idea in this
- module - the <TMPL_LOOP> - was entirely his.</P>
- <P>Fixes, Bug Reports, Optimizations and Ideas have been generously
- provided by:</P>
- <PRE>
- Richard Chen
- Mike Blazer
- Adriano Nagelschmidt Rodrigues
- Andrej Mikus
- Ilya Obshadko
- Kevin Puetz
- Steve Reppucci
- Richard Dice
- Tom Hukins
- Eric Zylberstejn
- David Glasser
- Peter Marelas
- James William Carlson
- Frank D. Cringle
- Winfried Koenig
- Matthew Wickline
- Doug Steinwand
- Drew Taylor
- Tobias Brox
- Michael Lloyd</PRE>
- <P>Thanks!</P>
- <P>
- <HR>
- <H1><A NAME="public cvs server">PUBLIC CVS SERVER</A></H1>
- <P>HTML::Template now has a publicly accessible CVS server provided by
- SourceForge (www.sourceforge.net). You can access it by going to
- <A HREF="http://sourceforge.net/cvs/?group_id=1075.">http://sourceforge.net/cvs/?group_id=1075.</A> Give it a try!</P>
- <P>
- <HR>
- <H1><A NAME="author">AUTHOR</A></H1>
- <P>Sam Tregar, <A HREF="mailto:sam@tregar.com">sam@tregar.com</A> (you can also find me on the mailing list
- at <A HREF="mailto:htmltmpl@lists.vm.com">htmltmpl@lists.vm.com</A> - join it by sending a blank message to
- <A HREF="mailto:htmltmpl-subscribe@lists.vm.com).">htmltmpl-subscribe@lists.vm.com).</A></P>
- <P>
- <HR>
- <H1><A NAME="license">LICENSE</A></H1>
- <P>HTML::Template : A module for using HTML Templates with Perl</P>
- <P>Copyright (C) 1999 Sam Tregar (<A HREF="mailto:sam@tregar.com">sam@tregar.com</A>)</P>
- <P>This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.</P>
- <P>This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.</P>
- <P>You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- USA</P>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> HTML::Template - Perl module to use HTML Templates from CGI scripts</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-