HTML-Macro

 view release on metacpan or  search on metacpan

Macro.pm  view on Meta::CPAN


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.

=head2 ifdef

HTML::Macro also provides the <if def="variable-name"> conditional.  This
construct evaluates to true if variable-name is defined and has a true
value.  It might have been better to name this something different like <if
set="variable"> ? Sometimes there is a need for if (defined (variable)) in
the perl sense.  Also we occasionally want <if ndef="var"> but just use <if
def="var"><else/> instead which seems adequate if a little clumsy.

=head1 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.

HTML::Macro also supports an include path.  This allows common "part" files
to be placed in a single central directory.  HTML::Macro::push_incpath adds
to the path, as in $htm->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. (Note that HTML::Macro never calls chdir
as part of an effort to be thread-safe).

Also note that during the processing of an included file, the folder in
which the included file resides is pushed on to the incpath.  This means
that relative includes work as you would expect in included files; a file
found in a directory relative to the included file takes precedence over
one found in a directory relative to the including file (or HTML::Macros
global incpath).

=head1 Loops

    The <loop> tag and the corresponding HTML::Macro::Loop object provide
for repeated blocks of HTML, with subsequent iterations evaluated in
different contexts.  Typically you will want to select rows from a database
(lines from a file, files from a directory, etc), and present each
iteration in succession using identical markup.  You do this by creating a
<loop> tag in your template file containing the markup to be repeated, and
by creating a correspondingly named Loop object attached to the HTML::Macro
and containing all the data to be interpolated.  Note: this requires all
data to be fetched and stored before it is applied to the template; there
is no facility for streaming data.  For the intended use this is not a
problem.  However it militates against using HTML::Macro for text
processing of very large datasets.

  <loop id="people">
    <tr><td>#first_name# #last_name#</td><td>#email#</td></tr>
  </loop>

    The loop tag allows the single attribute "id" which can be any
    identifier.  Loop tags may be nested.  If during processing no matching
    loop object is found, a warning is produced and the tag is simply
    ignored.

  $htm = new HTML::Macro;
  $loop = $htm->new_loop('people', 'id', 'first_name', 'last_name', 'email');
  $loop->push_array (1, 'frank', 'jones', 'frank@hotmail.com');

  Create a loop object using HTML::Macro::new_loop (or
  HTML::Macro::Loop::new_loop for a nested loop).  The first argument is
  the id of the loop and must match the id attribute of a tag in the
  template (the match is case sensitive).  The remaining arguments are the
  names of loop variables.

  Append loop iterations (rows) by calling push_array with an array of
  values corresponding to the loop variables declared when the loop was
  created.

  An alternative is to use push_hash, which is analogous to
HTML::Macro::set_hash; it sets up multiple variable substitutions.  If you
use push_hash you don't have to declare the names of the variables when you
create the loop object.  This allows them to be taken out of a hash and
bound late, for example by names returned in a database query.

  pushall_arrays is a shortcut that allows a number of loop iterations to
be pushed at once.  It is typically used in conjunction with
DBI::selectall_arrayref.

  is_empty returns a true value iff the loop has at least one row.

  keys returns a list of variable names defined in the (last row of the)
  loop.

=head1 Eval

  <eval expr="perl expression"> ... </eval>

  You can evaluate arbitrary perl expressions (as long as you can place
  them in an XML attribute between double quotes!).  The expression is
  subject to macro substition, placed in a block and invoked as an
  anonymous function whose single argument is an HTML::Macro object
  representing the nested scope.  Any values set in the perl expression
  thus affect the markup inside the eval tag.  The perl is evaluated after
  setting the package to the HTML::Macro caller's package.

  Note: typically we only use this to make a function call, and it would
  probably be more efficient to optimize for that case - look for the
  special case <eval function=""> to be implemented soon.  Also we might
  like to provide a singleton eval that would operate in the current scope:
  <eval function="perl_function" />.




( run in 1.060 second using v1.01-cache-2.11-cpan-140bd7fdf52 )