Macro(3)

NAME
HTML::Macro - generate dynamic HTML pages using templates

SYNOPSIS
  use HTML::Macro;
  $ifp = HTML::Macro->new();
  $ifp->declare ('var', 'missing');
  $ifp->set ('var', 'value');
  $ifp->print ('test.html');

DESCRIPTION
HTML::Macro is a module to be used behind a web server (in CGI scripts). It provides a convenient mechanism for generating HTML pages by combining "dynamic" data derived from a database or other computation with HTML templates that represent fixed or "static" content of a page.

There are many different ways to accomplish what HTML::Macro does, including ASP, embedded perl, CFML, etc, etc. The motivation behind HTML::Macro is to keep everything that a graphic designer wants to play with *in a single HTML template*, and to keep as much as possible of what a perl programmer wants to play with *in a perl file*. Our thinking is that there are two basically dissimilar tasks involved in producing a dynamic web page: graphic design and programming. Even if one person is responsible for both tasks, it is useful to separate them in order to aid clear thinking and organized work. I guess you could say the main motivation for this separation is to make it easier for emacs (and other text processors, including humans) to parse your files: it's yucky to have a lot of HTML in a string in your perl file, and it's yucky to have perl embedded in a special tag in an HTML file.

That said, HTML::Macro does provide for some simple programming constructs to appear embedded in HTML code. Think of it as a programming language on a similar level as the C preprocessor. HTML::Macro "code" is made to look like HTML tags so it will be fairly innocuous for most HTML-oriented editors to deal with. At the moment HTML::Macro suports variables, conditionals, loops, file interpolation and quoting (to inhibit all of the above). HTML::Macro variables are always surrounded with single or double hash marks: "#" or "##". Variables surrounded by double hash marks are subject to html entity encoding; variables with single hash marks are substituted "as is" (like single quotes in perl or UNIX shells). Conditionals are denoted by the <if> and <else> tags, and loops by the <loop> tag.

Usage:

Create a new HTML::Macro:
  $ifp = HTML::Macro->new();

Optionally, declare the names of all the variables that will be substituted on this page. This has the effect of defining the value '' for all these variables.
  $ifp->declare ('var', 'missing');

Set the values of one or more variables using HTML::Macro::set.

  $ifp->set ('var', 'value');
Or use IF:Page::set_hash to set a whole bunch of values at once. Typically used with the value returned from a DBI::fetchrow_hashref.

  $ifp->set_hash ( {'var' => 'value' } );
Finally, process the template and print the result using HTML::Macro::print, or save the value return by HTML::Macro::process.

    open CACHED_PAGE, '>page.html';
    print CACHED_PAGE, $ifp->process ('templates/page_template.html');
    close CACHED_PAGE;
    - or -
    $ifp->print ('test.html');
As a convenience the IF:Page::print function prints the processed template that would be returned by HTML::Macro::process, preceded by appropriate HTTP headers (Content-Type and no-cache directives).

HTML::Macro::process attempts to perform a substitution on any word beginning and ending with single or double hashmarks (#) , such as ##NAME##. A word is any sequence of alphanumerics and underscores. If the HTML::Macro has a matching variable, its value is substituted for the word in the template everywhere it appears. A matching variable may match the template word literally, or it may match one of the following:

the word with the delimiting hash marks stripped off ('NAME' in the example) the word without delimiters lowercased ('name') the word without delimiters uppercased ('NAME')

A typical usage is to stuff all the values returned from DBI::fetchrow_hashref into an HTML::Macro. Then SQL column names are to be mapped to template variables. Databases have different case conventions for column names; providing the case insensitivity and stripping the underscores allows templates to be written in a portable fashion while preserving an upper-case convention for template variables.

HTML entity quoting

Variables surrounded by double delimiters are subject to HTML entity encoding. That is, >, < and "" occuring in the variables value are replaced by their corresponding HTML entities. Variables surrounded by single delimiters are not quoted; they are substituted "as is"

Conditionals

Conditional tags take one of the following forms:

<if expr="perl expression">
 HTML block 1 <else/>
 HTML block 2 </if>

or

<if expr="perl expression">
 HTML block 1 <else>
 HTML block 2 </else> </if>

or simply

<if expr="perl expression">
 HTML block 1 </if>

Conditional tags are processed by evaluating the value of the "expr" attribute as a perl expression. The entire conditional tag structure is replaced by the HTML in the first block if the expression is true, or the second block (or nothing if there is no else clause) if the expressin is false.

Conditional expressions are subject to variable substitution, allowing for constructs such as:

You have #NUM_ITEMS# item<if "#NUM_THINGS# > 1">s</if> in your basket.

File Interpolation

It is often helpful to structure HTML by separating commonly-used chunks (headers, footers, etc) into separate files. HTML::Macro provides the <include/> tag for this purpose. Markup such as <include/ file="file.html"> gets replaced by the contents of file.html, which is itself subject to evaluation by HTML::Macro. If the "asis" attribute is present: <include/ file="quoteme.html" asis>, the file is included "as is"; without any further evaluation.

Also, HTML::Macro provides support for an include path. This allows common "part" files to be placed in a common place. HTML::Macro::push_incpath adds to the path, as in $ifp->push_incpath ("/path/to/include/files"). The current directory (of the file being processed) is always checked first, followed by each directory on the incpath. When paths are added to the incpath they are always converted to absolute paths, relative to the working directory of the invoking script. Thus, if your script is running in "/cgi-bin" and calls push_incpath("include"), this adds "/cgi-bin/include" to the incpath.

Quoting

The preceding transformations can be inhibited by the use of the "<quote>" tag. Any markup enclosed by <quote> ... </quote> is passed on as-is. quote tags may be nested to provide for multiple passes of macro substitution.

    This could be useful if you need to include markup like <if> in your
    output, although that could be more easily accomplished by the usual
    HTML entity encodings: escaping < with &lt; and so on.  The real reason
    this is here is to enable multiple passes of HTML::Macro to run on "proto"
    templates that just generate other templates.
Quote tags have an optional "preserve" attribute. If "preserve" is present, its value is evaluated (as with if above), and if the result is true, the quote tag is preserved in the output. Otherwise, the tag is swallowed and the quoting behavior is inhibited. So:

<quote preserve="1">xyzzy<include/ file="foo"></quote>

would be passed over unchanged,

and

<quote preserve="0"><include/ file="foo"></quote>

would be replaced by the contents of the file named "foo".

Loops

Finally, the <loop> tag provides for repeated blocks of HTML, with subsequent iterations evaluated in different contexts. For more about loops, see the IF:Page::Loop documentation.

HTML::Macro is copyright (c) 2000 by Michael Sokolov and Interactive Factory (sm). All rights are reserved.

AUTHOR
Michael Sokolov, sokolov@ifactory.com

SEE ALSO HTML::Macro::Loop
perl(1).