This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: HTML/Mason/Interp,  Next: HTML/Mason/MethodMaker,  Prev: HTML/Mason/Devel,  Up: Module List

Mason Component Interpreter
***************************

NAME
====

   HTML::Mason::Interp - Mason Component Interpreter

SYNOPSIS
========

     my $i = new HTML::Mason::Interp (data_dir=>'/usr/local/mason',
                                      comp_root=>'/usr/local/www/htdocs/',
                                      ...other params...);

DESCRIPTION
===========

   Interp is the Mason workhorse, executing components and routing their
output and errors to all the right places. In a mod_perl environment,
Interp objects are handed off immediately to an ApacheHandler object which
internally calls the Interp implementation methods. In that case the only
user method is the new() constructor.

   If you want to call components outside of mod_perl (e.g. from CGI or a
stand-alone Perl script), see the STANDALONE MODE section below.

PARAMETERS FOR new() CONSTRUCTOR
================================

allow_recursive_autohandlers
     True or undef. Default is true as of verison 0.85. If true,
     autohandlers apply both to their own directories and all
     subdirectories; if undef, only to their own directories. See the
     Devel/autohandlers section of the Component Developer's Guide for a
     discussion of the pros and cons.

autohandler_name
     File name used for autohandlers. Default is "autohandler". If undef,
     Mason will not look for autohandlers.

code_cache_max_size
     Specifies the maximum size, in bytes, of the in-memory code cache
     where components are stored. e.g.

          code_cache_max_size => 20*1024*1024
          code_cache_max_size => 20_000_000

     Default is 10 MB. See the Admin/Code Cache section of the *Admin
     Guide* for further details.

comp_root
     The required Mason component root. All components live under the
     comp_root.

     You may also specify multiple component roots to be searched in the
     spirit of Perl's @INC. To do so you must specify a list of lists:

          comp_root => [[key1, root1], [key2, root2], ...]

     Each pair consists of a key and root.  The key is a string that
     identifies the root mnemonically to a component developer.  Data cache
     and object directories are split up by these keys to make sure
     different components sharing the same path have different cache and
     object files. The key is also included whenever Mason prints the
     component title, as in an error message.

     For example:

          comp_root => [['private', '/usr/home/joe/comps'], ['main', '/usr/local/www/htdocs']]

     This specifies two component roots, a main component tree and a
     private tree which overrides certain components.  The order is
     respected ala @INC, so 'private' is searched first and 'main' second.

current_time
     Overrides the time returned by $m->time with a fixed Perl time() value
     (seconds since the epoch). On time-sensitive sites, this can be used
     to set up port-based time/date simulations, e.g. a port that looks one
     day into the future.

     With no current_time parameter (the default), $m->time reports the
     true time.

data_dir
     The required Mason data directory. Mason's various data directories
     (obj, cache, debug, etc), live within the data_dir.

data_cache_dir
     Specifies an absolute directory for data cache files. By default, it
     lives under data_dir/cache.

dhandler_name
     File name used for dhandlers. Default is "dhandler". If undef, Mason
     will not look for dhandlers.

max_recurse
     The maximum component stack depth the interpreter is allowed to
     descend before signalling an error.  Default is 32.

out_method
     Indicates where to send output. If out_method is a reference to a
     scalar, output is appended to the scalar.  If out_method is a
     reference to a subroutine, the subroutine is called with each output
     string. For example, to send output to a file called "mason.out":

          my $fh = new IO::File ">mason.out";
          ...
          out_method => sub { $fh->print($_[0]) }

     By default, out_method prints to standard output. (In a mod_perl
     environment this is automatically redirected to the HTTP client.)

out_mode
     Specifies one of two ways to send output, 'batch' or 'stream'.  In
     batch mode Mason computes the entire page in a memory buffer and then
     transmits it all at once. In stream mode Mason outputs data as soon as
     it is computed. (This does not take into account buffering done by
     Apache or the O/S.) The default mode is batch.  See the Admin/staging
     vs production section of the *Admin Guide* for a discussion of the
     trade-offs.

parser
     Parser object for compiling components on the fly. If omitted, creates
     a parser with default parameters.

preloads
     A list of component paths, optionally with glob wildcards, to load
     when the interpreter initializes. e.g.

          preloads => ['/foo/index.html','/bar/*.pl']

     Default is the empty list. This should only be used for components
     that are frequently viewed and rarely updated.  See the
     Admin/preloading section of the *Admin Guide* for further details.

static_file_root
     Absolute path to prepend to relative filenames passed to
     `$m->file()'. Does not require a trailing slash. For example, if the
     file root is '/foo/bar', then `$m->file('baz/bap')' will read the file
     '/foo/bar/baz/bap'. Undefined by default; if left undefined, relative
     path names to `$m->file()' are prepended with the current component
     directory.

system_log_events
     A string value indicating one or more events to record in the system
     log, separated by "|". Default is to log nothing.

system_log_file
     Absolute path of system log.  Default is data_dir/etc/system.log.

system_log_separator
     Separator to use between fields on a line in the system log. Default
     is ctrl-A ("\cA").

use_data_cache
     True or undef, default is true. Specifies whether the $m->cache and
     related commands are operational.  You may need to disable data
     caching temporarily for debugging purposes, but normally this should
     be left alone.

use_object_files
     True or undef, default is true.  Specifies whether Mason creates
     object files to save the results of component parsing. You may want to
     turn off object files for disk space reasons, but otherwise this
     should be left alone.

use_reload_file
     True or undef, default is undef. If true, disables Mason's automatic
     timestamp checking on component source files, relying instead on an
     explicitly updated Admin/reload file.

verbose_compile_error
     True or undef, default is undef. If true, component compile errors are
     followed with the full component source, annotated with line numbers,
     to better interpret the error message. Does not affect runtime errors.

ACCESSOR METHODS
================

   All of the above properties have standard accessor methods of the same
name. In general, no arguments retrieves the value, and one argument sets
and returns the value.  For example:

     my $interp = new HTML::Mason::Interp (...);
     my $p = $interp->parser;
     my $comproot = $interp->comp_root;
     $interp->out_method(\$buf);

   The following properties can be queried but not modified: comp_root,
data_dir, system_log_file, system_log_separator, preloads.

OTHER METHODS
=============

   This method sets a global to be used in components. `varname' is a
variable name, optionally preceded with a prefix (`$', `@', or %); if the
prefix is omitted then `$' is assumed. `varname' is followed by a value,
in the case of a scalar, or by one or more values in the case of a list or
hash.  For example:

     # Set a global variable $dbh containing the database handle
     $interp->set_global(dbh => DBI->connect(...));

     # Set a global hash %session from a local hash
     $interp->set_global('%session', %s);

   The global is set in the package that components run in: usually
`HTML::Mason::Commands', although this can be overridden via the Parser
parameter Parser/in_package.  The lines above, for example, are equivalent
to:

     $HTML::Mason::Commands::dbh = DBI->connect(...);
     %HTML::Mason::Commands::session = %s;

   assuming that in_package has not been changed.

   Any global that you set should also be registered with the Parser
parameter Parser/allow_globals; otherwise you'll get warnings from strict.

STANDALONE MODE
===============

   Although Mason is most commonly used in conjunction with mod_perl,
there is also a functional API that allows you to use Mason from CGI
programs or from stand-alone Perl scripts.  In the latter case Mason can be
used as a glorified Text::Template, producing a set of files from
components, or used to generate a flat version of a componentized site.

   When using Mason outside of mod_perl, just create a Parser and Interp
object; you do not need the ApacheHandler object.  Once you've created an
interpreter, the main thing you'll want to do with it is call a component
and do something with the output. To call a component, use Interp's exec()
method:

     $interp->exec(<comp> [,<..list of component params..>]);

   where comp is a component path or component object.

   Component parameters are given as a series of name/value pairs, just as
they are with `$m->comp'. exec returns the return value of the component.
Component output is sent to standard output by default, but you can change
this by specifying out_method.

   Here is a skeleton script that calls a component and places the output
in a file:

     my $outbuf;
     my $parser = new HTML::Mason::Parser;
     my $interp = new HTML::Mason::Interp (parser=>$parser,
     					  comp_root=>'<component root>',
     					  data_dir=>'<data directory>',
     					  out_method=>\$outbuf);
     my $retval = $interp->exec('<component path>',<args>...);
     open(F,">mason.out");
     print F $outbuf;
     close(F);
     print "return value of component was: $retval\n";

AUTHOR
======

   Jonathan Swartz, swartz@pobox.com

SEE ALSO
========

   HTML::Mason, HTML::Mason::Parser, HTML::Mason::ApacheHandler,
HTML::Mason::Admin


File: pm.info,  Node: HTML/Mason/MethodMaker,  Next: HTML/Mason/Parser,  Prev: HTML/Mason/Interp,  Up: Module List

Used to create simple get & get/set methods in other classes
************************************************************

NAME
====

   HTML::Mason::MethodMaker - Used to create simple get & get/set methods
in other classes

SYNOPSIS
========

     use HTML::Mason::MethodMaker ( read_only => 'foo',
                                    read_write => [ qw( bar baz ) ] );

DESCRIPTION
===========

   This automates the creation of simple accessor methods.

USAGE
=====

   This module creates methods when it is use'd by another module.  There
are two types of methods: 'read_only' and 'read_write'.

   Attributes specified as 'read_only' get an accessor that only returns
the value of the attribute.  Presumably, these attributes are set via more
complicated methods in the class or as a side effect of one of its methods.

   Attributes specified as 'read_write' will take a single optional
parameter.  If given, this parameter will become the new value of the
attribute.  This value is then returned from the method.  If no parameter
is given, then the current value is returned.


File: pm.info,  Node: HTML/Mason/Parser,  Next: HTML/Mason/Request,  Prev: HTML/Mason/MethodMaker,  Up: Module List

Mason Component Parser
**********************

NAME
====

   HTML::Mason::Parser - Mason Component Parser

SYNOPSIS
========

     my $p = new HTML::Mason::Parser (...params...);

DESCRIPTION
===========

   A Parser object translates components into Perl subroutines. Parsers
are typically embedded within (and used by) Interp objects.

PARAMETERS FOR new() CONSTRUCTOR
================================

   These parameters affect the way that components are translated into
Perl code. If you change a Parser's options, you must remove any
previously created object files for the changes to take effect.  See also
Admin/Object files.

allow_globals
     List of variable names, complete with prefix (`$@%'), that you intend
     to use as globals in components.  Normally global variables are
     forbidden by strict, but any variable mentioned in this list is
     granted a reprieve via a "use vars" statement. For example:

          allow_globals => [qw($DBH %session)]

     In a mod_perl environment, $r (the request object) is automatically
     added to this list.

default_escape_flags
     Escape flags to apply to all <% %> expressions by default. The current
     valid flags are

          h - escape for HTML ('<' => '&lt;', etc.)
          u - escape for URL (':' => '%3A', etc.)

     The developer can override default escape flags on a per-expression
     basis; see Devel/escaping_expressions.

ignore_warnings_expr
     Regular expression indicating which warnings to ignore when compiling
     subroutines. Any warning that is not ignored will prevent the
     component from being compiled and executed. For example:

          ignore_warnings_expr =>
              'Global symbol.*requires explicit package'

     If undef, all warnings are heeded; if '.', all warnings are ignored.

     By default, this is set to 'Subroutine .* redefined'.  This allows you
     to declare global subroutines inside <%once> sections and not receive
     an error when the component is reloaded.

in_package
     Indicates the name of the package you wish your components to run in.
     This way different applications or virtual hosts can be run in
     different name spaces.  Default is `HTML::Mason::Commands'.

postamble
     A piece of Perl code to insert at the end of every compiled
     subroutine. Blank by default. See Parser/preamble.

postprocess
     Sub reference that is called to postprocess the code and text portions
     of a compiled component, just before it is assembled into its final
     subroutine form.  The sub is called with two parameters, a scalar
     reference to the script and a string containing either "perl" or
     "alpha" depending on whether the string is code or text respectively.
     The sub is expected to process the string in-place. It will be called
     multiple times, once for each piece of code and text.

     This is the ideal place to translate accents into HTML entities.  It
     could also be used to strip out comments that you have in your HTML
     files that you don't want the end user to see. See Parser/preprocess.

preamble
     A piece of Perl code to insert at the beginning of every compiled
     subroutine. Blank by default, but ApacheHandler adds the line

          use vars qw($r);

     to suppress strict warnings about uses of global $r (the Apache
     request object). See Parser/postamble.

preprocess
     Sub reference that is called to preprocess each component before
     Parser does it's magic.  The sub is called with a single parameter, a
     scalar reference to the script.  The sub is expected to process the
     script in-place.   This is one way to extend the HTML::Mason syntax
     with new tags, etc. See Parser/postprocess.

taint_check
     This flag allows Mason to work when taint checking is on (e.g.
     PerlTaintCheck or -T flag).  If true, Mason will pass all component
     source and filenames through a dummy regular expression match to
     untaint them. In the future this option may become more sophisticated
     to allow stricter checks. Default is false.

use_strict
     Indicates whether to use strict in compiled subroutines.  Default is
     true.

ACCESSOR METHODS
================

   Most of the above properties have standard accessor methods of the same
name: no arguments retrieves the value, and one argument sets it.  For
example:

     my $parser = new HTML::Mason::Parser;
     my $strictmode = $parser->use_strict;
     $parser->use_strict(1);

   The only exception is Parser/allow_globals, which works a bit
differently.

OTHER METHODS
=============

allow_globals (varnames)
     Called with no arguments, this returns the value of allow_globals as a
     list.  Called with one or more variable names, it appends the names to
     the existing list, removing duplicates if any.

     This method compiles a component source script into an Component
     object.  The source may be passed in as a string in *script*, or as a
     filename in *script_file*.

     Returns the new Component object on success, or undef if an error
     occurred. error is an optional scalar reference filled with the error
     message.

     Example of usage:

          # Make a component
          my $comp = $parser->make_component
              (script=>'<%perl>my $name = "World";</%perl>Hello <% $name %>!',
               error => \my $error)
            or die "error while compiling component: $error";

          # Call it from inside another component
          $m->comp($comp);

     make_dirs traverses a tree of components, compiles any out-of-date
     components into object files, and reports errors.

     comp_root and data_dir contain the Mason component root and data
     directory respectively. These are required.

     *paths* is a reference to a list of component paths to make
     recursively. By default, makes '/' (the entire component tree).

     verbose is a flag indicating whether to report components compiled
     and directories created. True by default.

     *predicate* is a subroutine that takes one argument, the component
     source file, and returns true or false indicating whether or not to
     try to compile it.  By default *predicate* ignores all filenames
     ending with "~".

     *dir_create_mode* contains the permissions mode for creating new
     directories, by default 0775.

     *update_reload_file* is a flag indicating whether to update a reload
     file in the data directory as components are recompiled. False by
     default.

     Example of usage:

          #!/usr/bin/perl
          use HTML::Mason;
          use HTML::Mason::ApacheHandler;  # load explicitly to bring in special $m-> commands
          
          my $p = new HTML::Mason::Parser;
          $p->allow_globals(qw($r));       # allow Apache $r global
          $p->make_dirs (comp_root=>'/usr/home/swartz/web/comps',
                         data_dir=>'/usr/home/swartz/web/mason');

AUTHOR
======

   Jonathan Swartz, swartz@pobox.com

SEE ALSO
========

   HTML::Mason, HTML::Mason::Interp, HTML::Mason::ApacheHandler,
HTML::Mason::Admin


File: pm.info,  Node: HTML/Mason/Request,  Next: HTML/Mason/Tests,  Prev: HTML/Mason/Parser,  Up: Module List

Mason Request Class
*******************

NAME
====

   HTML::Mason::Request - Mason Request Class

SYNOPSIS
========

     $m->abort (...)
     $m->comp (...)
     etc.

DESCRIPTION
===========

   The Request API is your gateway to all Mason features not provided by
syntactic tags. Mason creates a new Request object for every web request.
Inside a component you access the current request object via the global $m.

COMPONENT PATHS
===============

   The methods `Request' in this node, `Request' in this node, `Request'
in this node, and `Request' in this node take a component path as argument.

   * If the path is absolute (starting with a '/'), then the component is
     found relative to the component root.

   * If the path is relative (no leading '/'), then the component is found
     relative to the current component directory.

   * If the path matches both a subcomponent and file-based component, the
     subcomponent takes precedence.

METHODS
=======

   Ends the current request, finishing the page without returning through
components. The optional argument specifies the return value from
`Interp::exec'; in a web environment, this ultimately becomes the HTTP
status code.

   abort() is implemented via die() and can thus be caught by eval().

   Under the current implementation, any pending `<%filter>' sections will
not be applied to the output after an abort.  This is a known bug but
there is no easy workaround.

   The methods aborted and aborted_value return a boolean indicating
whether the current request was aborted and the argument with which it was
aborted, respectively. These would be used, for example, after an eval()
returned with a non-empty `$@'.

   Returns true or undef indicating whether the current request was aborted
with abort.

   Returns the argument passed to abort when the request was aborted.
Returns undef if the request was not aborted or was aborted without an
argument.

   Returns the current base component for method and attributes.
Generally set to the original page component; however, if you invoke
call_method on a component, base_comp is dynamically set to that component
until call_method exits. See `Devel' in this node for examples of usage.

   `$m->cache' lets you store and retrieve the results of computation for
improved performance. Each component has its own data cache for storing
one or more key/value pairs. The cache is implemented as a DBM database.
See the `Devel' in this node section of the *Component Developer's Guide*
for examples and caching strategies.

   The argument to action is one of:

   o retrieve: returns the cache value if successful, or undef if there
was no value or if it has expired.

   o store: stores a new cache value under the given key.  Default key is
'main'.  Returns the value being stored if successful.

   o expire: expires a given cache value or values.  key may be a single
key or a list reference. Default key is 'main'.

   o keys: returns a list of all the keys in the cache.

   value defines what to store. It can be a scalar or a reference to an
arbitrary data structure. The allowable size depends on your DBM
implementation.

   *keep_in_memory* indicates whether to save the value in memory once it
is retrieved. Default is 0, meaning that the value will be retrieved from
the cache file each time. If 1, each child server that retrieves this
value will save its own copy, which can result in substantial memory usage
for larger values. Use sparingly.

   The various expiration options are:

   o *expire_at*: takes an absolute expiration time, in Perl time() format
(number of seconds since the epoch)

   o *expire_in*: takes a relative expiration time of the form
"<num><unit>", where <num> is a positive number and <unit> is one of
seconds, minutes, hours, days, or weeks, or any abbreviation thereof.
E.g. "10min", "30m", "1hour".

   o *expire_next*: takes a string, either 'hour' or 'day'. It indicates
an expiration time at the top of the next hour or day.

   o *expire_if*: calls a given anonymous subroutine and expires if the
subroutine returns a non-zero value. The subroutine is called with one
parameter, the time when the cache value was last written.

   Uses `$m->cache' to cache the entire output and/or the return value of
the current component.  It is typically used right at the top of an
`<%init%>' section.

   To cache the component's output:

     <%init>
         return if $m->cache_self(expire_in=>'3 hours'[, key=>'fookey']);
         ... <rest of init> ...
     </%init>

   To cache the component's return value:

     <%init>
         my ($retval,$cached) = $m->cache_self(expire_in=>'3 hours'[, key=>'fookey']);
         return $retval if $cached;
         ... <rest of init> ...
     </%init>

   This only works with scalar and reference return values.

   `$m->cache_self' handles both the retrieve and store, so you can pass
both kinds of options to it. See `$m->cache' for an explanation of options.

   `$m->cache_self' uses a bit of magic to accomplish everything in one
line.  You can use it without understanding it, but if you're curious,
here's how it works:

   o A component foo calls `$m->cache_self' for the first time.

   o `$m->cache_self' sees that the cache is empty and calls foo again
recursively, with a STORE option to capture its content into a buffer.

   o foo again calls `$m->cache_self' which immediately returns 0 this
time.

   o foo goes about its business and generates content into the
`$m->cache_self' buffer.

   o When control is returned to `$m->cache_self', it stores the content
and return value in the cache and also outputs the content normally.
Finally `$m->cache_self' returns the list (retval,1) which in turn causes
foo to return immediately.

   Returns the arguments passed by the component at the specified stack
level. Use a positive argument to count from the current component and a
negative argument to count from the component at the bottom of the stack.
e.g.

     $m->caller_args(0)   # arguments passed to current component
     $m->caller_args(1)   # arguments passed to component that called us
     $m->caller_args(-1)  # arguments passed to first component executed

   When called in scalar context, a hash reference is returned.  When
called in list context, a list of arguments (which may be assigned to a
hash) is returned.

   With no arguments, returns the current component stack as a list of
component objects, starting with the current component and ending with the
top-level component. With one numeric argument, returns the component
object at that index in the list. Use a positive argument to count from
the current component and a negative argument to count from the component
at the bottom of the stack. e.g.

     my @comps = $m->callers   # all components
     $m->callers(0)            # current component
     $m->callers(1)            # component that called us
     $m->callers(-1)           # first component executed

   Calls the next component in the content wrapping chain; usually called
from an autohandler. With no arguments, the original arguments are passed
to the component.  Any arguments specified here serve to augment and
override (in case of conflict) the original arguments. Works like
`$m->comp' in terms of return value and scalar/list context.  See the
`Devel' in this node section of the *Component Developer's Guide* for
examples.

   Clears the Mason output buffer. Any output sent before this line is
discarded. Useful for handling error conditions that can only be detected
in the middle of a request.

   clear_buffer only works in batch output mode, and is thwarted by
flush_buffer.

   Calls the component designated by comp with the specified option/value
pairs. comp may be a component path or a component object.

   Components work exactly like Perl subroutines in terms of return values
and context. A component can return any type of value, which is then
returned from the `$m->comp' call.

   The <& &> tag provides a convenient shortcut for `$m->comp'.

   Returns 1 if *comp_path* is the path of an existing component, 0
otherwise.

   Returns the number of this request, which is unique for a given request
and interpreter.

   Returns the current component object.

   Used from a top-level component or dhandler, this method aborts the
current request and restarts with the next applicable dhandler up the
tree. If no dhandler is available, an error occurs.  This method bears no
relation to the Apache DECLINED status except in name.

   Returns the current size of the component stack.  The lowest possible
value is 1, which indicates we are in the top-level component.

   If the request has been handled by a dhandler, this method returns the
remainder of the URI or `Interp::exec' path when the dhandler directory is
removed. Otherwise returns undef.

   dhandler_arg may be called from any component in the request, not just
the dhandler.

   Given a *comp_path*, returns the corresponding component object or
undef if no such component exists.

   Returns the next component in the content wrapping chain, or undef if
there is no next component. Usually called from an autohandler.  See the
`Devel' in this node section of the *Component Developer's Guide* for
usage and examples.

   Returns a list of the remaining components in the content wrapping
chain. Usually called from an autohandler.  See the `Devel' in this node
section of the *Component Developer's Guide* for usage and examples.

   Returns the contents of filename as a string. filename may be an
absolute filesystem path (starting with a '/') or relative (no leading
'/'). If relative, Mason prepends the static file root, or the current
component directory if no static file root is defined.

   Returns the static file root, used by `$m->file' to resolve relative
filenames.

   Flushes the Mason output buffer. Under mod_perl, also sends HTTP
headers if they haven't been sent and calls $r->rflush to flush the Apache
buffer. Flushing the initial bytes of output can make your servers appear
more responsive.

   Returns the Interp object associated with this request.

   Print the given string. Rarely needed, since normally all HTML is just
placed in the component body and output implicitly. `$m->out' is useful if
you need to output something in the middle of a Perl block.

   `$m->out' should be used instead of print or `$r->print', since
`$m->out' may be redirected or buffered depending on the current state of
the interpreter.

   Returns the Parser object associated with this request.

   Given a *comp_path*, returns the corresponding absolute component path.

   Like `$m->comp', but returns the component output as a string instead
of printing it. (Think sprintf versus printf.) The component's return
value is discarded.

   Returns the interpreter's notion of the current time in Perl time()
format (number of seconds since the epoch).

   By using `$m->time' rather than calling time() directly, you enable the
option of previewer or port-based time/date simulations. e.g.  a port that
looks one day into the future.

   Returns the arguments originally passed to the top level component.
When called in scalar context, a hash reference is returned. When called
in list context, a list of arguments (which may be assigned to a hash) is
returned.

   Returns the component originally called in the request. Note: because
of autohandlers this may or may not be the first component executed.

APACHE-ONLY METHODS
===================

   These additional methods are available when running Mason with mod_perl
and the ApacheHandler.

   Returns the ApacheHandler object associated with this request.

   Returns the Apache request object.  This is also available in the
global $r.

   Returns the CGI object used to parse any CGI parameters submitted to
the component, assuming that you have not changed the default value of the
ApacheHandler args_method parameter.  If you are using the 'mod_perl' args
method, then calling this method is a fatal error.  See the *Note
HTML/Mason/ApacheHandler: HTML/Mason/ApacheHandler, documentation for more
details.

AUTHOR
======

   Jonathan Swartz, swartz@pobox.com

SEE ALSO
========

   *Note HTML/Mason/Component: HTML/Mason/Component, *Note
HTML/Mason/ApacheHandler: HTML/Mason/ApacheHandler,


File: pm.info,  Node: HTML/Mason/Tests,  Next: HTML/Munger,  Prev: HTML/Mason/Request,  Up: Module List

Test harness for testing Mason
******************************

NAME
====

   HTML::Mason::Tests - Test harness for testing Mason

SYNOPSIS
========

     use HTML::Mason::Tests;

     my $group = HTML::Mason::Tests->new( name => 'name of group', description => 'tests something' );
     $group->add_test( name => 'foo',
                       description => 'tests foo',
                       component => <<'EOF'
     <%args>
     $foo => 1
     </%args>
     <% $foo %>
     EOF
                       expect => <<'EOF',
     1
     EOF
                     );

DESCRIPTION
===========

   This module is designed to automate as much as possible of the Mason
test suite.  It does tasks like write component files to disk, call them,
compare the actual results to the expected results, and more.  In
addition, it also is capable of printing out useful information about test
failures when run in verbose mode.  See the ADDITIONAL RUN MODES section
for more information.

   It also makes sure that any given group of tests provides all the
information needed to run them (test names, components and results, etc.).

   Now you have no excuse for writing new tests (and that goes double for
me!).

METHODS
=======

new
---

   Takes the following parameters:

   * name (required)

     The name of the entire group of tests.

   * description (required)

     What this group tests.

add_support
-----------

   Takes the following parameters:

   * path (required)

     The path that other components will expect this component to be
     reachable at.  All paths are prepended with the group name.  So '/bar'
     as a support component in the 'foo' group's ultimate path would be
     '/foo/bar'.

   * component

     Text of the support component.  This parameter must have a value
     unless the skip_component parameter is true.

   * skip_component

     If true, then the test harness will not write a component to disk for
     this test.

add_test
--------

   Takes the following parameters:

   * name (required)

     The name of this test.

   * description (required)

     What this test is testing.

   * component (required)

     Text of the component.

   * path (optional)

     The path that this component should written to.  As with support
     components, this path is prepended with the group's name.  If no path
     is given, the value of the name parameter is used.

   * call_path (optional)

     The path that should be used to call the component.  If none is given,
     then the value is the same as the path option, if that exists,
     otherwise it is /<group name>/<test name>.  If a value is given, it is
     still prepended by /<group name>/.

   * call_args (optional)

     The arguments that should be passed to the component, in list or hash
     reference form. If none is given, no arguments are passed.

   * parser_params

     This is a hash reference of parameters to be passed to the Parser->new
     method.

   * interp_params

     This is a hash reference of parameters to be passed to the Interp->new
     method.

   * interp

     Provide an HTML::Mason::Interp object to be used for the test.

   One of the following three options is required:

   * expect

     The text expected as a result of calling the component.  This
     parameter is _not_ required when running in `Create mode|ADDITIONAL
     RUN MODES' in this node.

   * expect_error

     A regex containing that will be matched against the error returned
     from the component execution.

   * skip_expect

     This causes the component to be run but its output is ignored.
     However, if the component execution causes an error this will cause
     the test to fail.  This is used in a few situations where it is
     necessary to just run a component as part the preparation for another
     test.

run
---

   Run the tests in the group.

Class methods
-------------

   These methods are provided since some tests may need to know these
values.

base_path
---------

   The base path under which the component root and data directory for the
tests are created.

comp_root
---------

   Returns the component root directory.

data_dir
--------

   Return the data directory

check_output ( actual => $actual_output, expect => $expected_output )
---------------------------------------------------------------------

   Given the parameters shown above, this method will check to see if the
two are equal.  If they're not equal, it will print out an error message
attempting to highlight the difference.

ADDITIONAL RUN MODES
====================

   The following additional modes are available for running tests.

Verbose mode
------------

   To turn this on, set the environment variables MASON_VERBOSE or
MASON_DEBUG as true or run the tests as 'make test TEST_VERBOSE=1'.  In
this mode, the run method will output information about tests as they are
run.  If a test fails, then it will also show the cause of the failure.

Debug mode
----------

   To turn this on, set the MASON_DEBUG environment variable to a true
value.  In this mode, the run method will print detailed information of
its actions.  This mode includes the output printed in VERBOSE mode.

Create mode
-----------

   If the individual tests are run from the command line with the
'-create' flag, then instead of checking the output of a component, the
test harness will simply output its results.  This allows you to cut and
paste these results back into the test file (assuming they are correct!).


File: pm.info,  Node: HTML/Munger,  Next: HTML/NEWS,  Prev: HTML/Mason/Tests,  Up: Module List

Module which simplifies the creation of web filters.
****************************************************

NAME
====

   HTML::Munger - Module which simplifies the creation of web filters.

SYNOPSIS
========

     use HTML::Munger;

     $munger = new HTML::Munger;
     $munger->set_munger(\&filter_function);
     $output = $munger->munge($URL, $selfURL, $input);

DESCRIPTION
===========

   HTML::Munger is a simple module which allows easy creation of web page
filtering software.  It was first written to build the pootifier at
http://pootpoot.com/?pootify

   The main task which this module performs is attempting to make all the
relative links on the filtered page absolute, so that images, and
hyperlinks work correctly.  It also makes frames and hyperlinks properly
filter back through the filter.

   This leaves two major tasks for the user of HTML::Munger: fetching the
original page, and building a simple munging function.

API
---

   There are really only three important functions you need to know how to
call in order to use this module:

new
     This is a simple constructor, which takes no arguments aside from the
     implicit class.  It returns a blessed reference which is used to call
     the other methods.

set_munger
     This method registers the filtering function you want to be called to
     produce the filtered text.  The function specified will be called
     repeatedly with short blocks of text.  For example, given the
     following HTML:

          <P>Hello</P><CENTER>The quick brown <I>fox</I></CENTER>

     The filtering function would be called three times, with 'Hello',
     'The quick brown ', and 'fox', respectively, as input.  The filter
     function is expected to return a string which will replace the given
     input in the output of the munge() call.

munge
     This method takes three arguments.  The first is the URL of the page
     which is being munged.  Note that the 'munge' method does NOT fetch
     the page for you!  It needs this information in order to make
     relative links in the page absolute.  The second argument is the URL
     of the filtering program.  This is used to make all hyperlinks and
     frames pass back through the filter.  Finally, it takes the input
     HTML as its third argument.  This method returns the munged HTML
     string, which can then be further parsed or sent to the user.

BUGS
====

   Hopefully none.

AUTHOR
======

   J. David Lowe, dlowe@pootpoot.com

SEE ALSO
========

   perl(1), HTML::Parser(3)


File: pm.info,  Node: HTML/NEWS,  Next: HTML/Navigation,  Prev: HTML/Munger,  Up: Module List

News for HTML::Embperl
======================

   * 22. Dec 2000

     After long time of talking, designing, developing, codeing and
     testing I am now happy to announce the first beta of Embperl 2.0. It
     has a totaly rewritten core and makes the way free for a lot of new
     possibilities...

     At the moment it's mainly a speed improvement and introduces caching
     of the (component) output. In the next releases I successively make
     the possibilities of this new architecture available. (see the readme
     below for some ideas what will happen).

     Since it's not yet ready for production use, it's only available from
     my ftp server at

     ftp://ftp.dev.ecos.de/pub/perl/embperl/HTML-Embperl-2.0b1.tar.gz

   * 4. Dec 2000

     After nearly a year of beta test, the final 1.3.0 release is out.
     Beside a lot of enhancements, EmbperlObject which allows you to build
     your web site out of small reusable objects in a OO-style, is the
     main improvement since 1.2.1.

   * 1. Dec 2000

     The slides from my talk on the O'Reilly Open Source Software
     Convention are now available at
     http://www.ecos.de/embperl/index.htm/ep/pod/oscon2000/index.html .

   * 15. Nov 2000

     Embperl 1.3b7 released

   * 18. Oct 2000

     Embperl 1.3b6 released

   * 20. Aug 2000

     Embperl 1.3b5 released

   * 17. July 2000

     Embperl 1.3b4 released

   * 22. Juni 2000

     On the O'Reilly Open Source Software Convention there is again a talk
     about Embperl Embperl - From Embedding Perl into HTML to Objects and
     XML

     http://www.oreillynet.com/pub/e_sess/863

     Slides are available at

     http://www.ecos.de/embperl/index.htm/ep/pod/oscon2000/index.html

   * 26. May 2000

     Embperl RPMs available

   * 26. Apr 2000

     Embperl 1.3b3 released

   * 25. Apr 2000

     Perlmonth starts a new article series about Embperl

     http://www.perlmonth.com/index.html?issue=11

   * 16. Apr 2000

     Added page about syntaxfiles for various editors

   * 20. Mar 2000

     Embperl now has it's own Mailinglist

   * 13. Mar 2000

     Tallyman is a free content management and shopping system based on
     Embperl

     http://sourceforge.net/projects/tallyman/

   * 13. Mar 2000

     Apache::iNcom is a free Web E-Commerce Application Framework based on
     Embperl.

     http://indev.insu.com/iNcom/incom.html

   * 11. Feb 2000

     Embperl 1.3b2 released. This release contains the new EmbperlObject
     which really simplify building a website out of small reusable pieces

   * 5. Jan 2000

     Embperl 1.2.1 released

   * 20. Dec 99

     Added Introduction to DBIx::Recordset

   * 4. Dec 99

     Added Page with WorldWide Mirrors

   * 17. Nov 99

     Embperl 1.2.0 released

   * 4. Nov 99

     Embperl 1.2b11 released

   * 7. Oct 99

     Embperl 1.2b10 released

   * 10. Sept 99

     Embperl 1.2b9 released

   * 10. Sept 99

     Embperl 1.2b9 released

   * 9. Sept 99

     Embperl 1.2b8 released

   * 8. Sept 99

     German Embperl Website is online

   * 30. Aug 99

     Embperl 1.2b7 released

   * 19. Aug 99

     Embperl 1.2b6 released

   * 12. Aug 99

     Article in german Unix magazine iX 9/99 about Embperl and
     DBIx::Recordset

     http://www.heise.de/ix/artikel/1999/09/137/

   * May/April/June 99

     Perlmonth has a column about Embperl

     http://www.perlmonth.com/columns/backend/server_setup.html?issue=1

   * 5. July 99

     Embperl 1.2b5 released

   * 1. July 99

     On the O'Reilly Open Source Software Convention there are two talks
     about Embperl Embperl and DBIx::Recordset - How to Easily Build a
     Database Driven Web Site

     http://conferences.oreilly.com/apache/conf_desc.html#c13

     New Stuff: Embedding Perl

     http://conferences.oreilly.com/perl3/conf_desc.html#p21



File: pm.info,  Node: HTML/Navigation,  Next: HTML/PageIndex,  Prev: HTML/NEWS,  Up: Module List

generic HTML navigation structure class
***************************************

NAME
====

   HTML::Navigation - generic HTML navigation structure class

SYNOPSIS
========

     my $nav = new HTML::Navigation();

     # a simple, one-level menu
     $nav->structure([
                      __callbacks__ => [ $callbacks ],
                      __param__ => 'param1',
                      'foo',
                      'bar',
                     ]);

     # output a two-item navigation menu with the `bar' item selected
     print $nav->output({ param1 => 'bar' });

DESCRIPTION
===========

   HTML::Navigation makes it easy to generate an HTML navigation structure
without forcing you into any particular layout or design.  All the output
is done by your own subroutines, which the module invokes as callbacks
(code refs).

   You supply the navigation structure and callbacks for generating
different bits of the output, and the module takes care of the rest.  You
may wonder what "the rest" refers to; what else there is to do except
generate output?  Well, HTML::Navigation really comes into its own with
nested (multi-level) navigation structures, including dynamically
generated ones.  The structures are ordered directed acyclic graphs where
each node is a menu item which can optionally have subnodes.

   See `"EXAMPLES"' in this node for the quickest way to learn how the
module works.

   Please note that parsing of the structure is currently performed when
output() is called rather than when new() is called.  This avoids
unnecessary calls to potentially expensive callbacks which may be given to
dynamically generate parts of the navigation structure.

METHODS
=======

new()
-----

     my $nav = new HTML::Navigation(structure => $structure);

   or

     my $nav = new HTML::Navigation();
     $nav->structure($structure);

   The two forms are identical in results.  Likewise you can specify a
`base_url' parameter instead of setting a base url via the base_url()
method.

structure()
-----------

     my $structure = $nav->structure();

     $nav->structure($new_structure);

   Reads/writes the navigation data structure.  See `"EXAMPLES"' in this
node for an extensive tutorial on how to form these data structures.

output()
--------

     my %CGI_params = map { $_ => $req->param($_) } qw/param1 param2/;
     my $out = $nav->output(\%CGI_params);

   Returns the HTML for a navigation menu, as defined by the `_navigation'
key in the frontend object.

dump_all_params()
-----------------

   Returns an array containing all the combinations of CGI parameters
required to select every element in the navigation structure.  Each
combination is in standard CGI QUERY_STRING format, i.e.

     param1=foo;param2=bar;param3=...

params()
--------

     sub unselected_callback {
       my ($nav, %p) = @_;

     # make unselected menu item a hyperlink
     return $nav->ahref(text   => $p{item},
                        params => [ $nav->params(%p) ]);
       }

   Helper method for figuring out what CGI parameters are needed to point
to the item described by `%p'.

ahref()
-------

     my $html = ahref(url    => 'http://www.foobar.com/baz.pl',
                      text   => 'click me', # defaults to the url parameter
                      params => {
                                 param1 => 'val1',
                                 param2 => 'val2',
                                },
                      # any other parameters get added as attributes, e.g.
                      class  => 'myclass', # <A ... CLASS="myclass" ...>
                      ...
                     );

   Convenient method for generating hyperlinks.  All parameters are
optional, but ahref() will moan if it can't figure out a sensible value
for HREF.  The value for the params key can be a hashref or an arrayref;
in the latter case the order of the parameters is preserved in the output.

query_string()
--------------

     # Set $query_string to `param1=foo%20bar;param2=baz'
     my $query_string = $nav->query_string([
                                            param1 => 'foo bar',
                                            param2 => 'baz',
                                           ]);

   This method provides an easy way of generating a string suitable for
appending to the end of a CGI URL in order to create GET queries.

   You can pass the parameters in either a hashref or an arrayref; in the
latter case the order given is preserved.

base_url()
----------

     my $base_url = $nav->base_url();
     $nav->base_url('foo.pl');

   Read/write a base url for the links generated by ahref() to default to
if no url parameter is given.

debug_level()
-------------

     my $current_level = $self->debug_level();

     $self->debug_level($new_level);

   Read/write debugging verbosity level (defaults to 0).

   Debugging appears on STDOUT.

TUTORIAL
========

   Here are some examples of navigation structures.  I will try to
introduce the concepts in increasing order of complexity.  The structures
are always suitable for passing to the structure() method, and each one
can be found as part of a fully working CGI script in the `eg' directory
so that you can experiment with them more yourself.

   Note that they are always arrayrefs rather than hashrefs so that the
ordering of the items is preserved.

A basic three-item, single-level menu
-------------------------------------

   This structure describes a single-level (no submenus) menu with three
items.  The value following `__param__' is the CGI parameter used to
determine which item is selected, and in this case is innovatively called
`param'.

     # Extract from eg/single.cgi
     [
      __param__ => 'param',
      __callbacks__ => [{
                         pre_items  => sub { "<ol>\n"  },
                         post_items => sub { "</ol>\n" },
                         pre_item   => sub { "  <li> " },
                         post_item  => sub { "\n"      },
                         unselected => sub {
                           my ($nav, %p) = @_;
                           return $nav->ahref(text => $p{item},
                                              params => [ $nav->params(%p) ]);
                         },
                         selected => sub {
                           my ($nav, %p) = @_;
                           return $p{item};
                         },
                        }],
      'item 1',
      'item 2',
      'item 3',
     ]

Basic callback types and ordering
---------------------------------

   The value following __callbacks__ is an arrayref containing one hashref
for each level of the navigation structure.  The example above has only
one level, so there is only one hashref inside the array ref.  The
hashrefs map types of callback to the callbacks themselves, which generate
all the output.  So in this example, the callbacks get invoked in the
following order:

     pre_items
       pre_item for item 1
       selected or unselected for item 1
       post_item for item 1

     pre_item for item 2
     selected or unselected for item 2
     post_item for item 2

     pre_item for item 3
     selected or unselected for item 3
     post_item for item 3
       post_items

   Output occurs when the output() method is called, which takes as its
sole argument a hashref describing the current CGI parameters.  It uses
this to determine whether an item is selected or not, so if it is called as

     $nav->output({ param => 'item 2' });

   then the callbacks will be invoked as follows:

     pre_items
       pre_item for item 1
       unselected for item 1
       post_item for item 1

     pre_item for item 2
     selected for item 2
     post_item for item 2

     pre_item for item 3
     unselected for item 3
     post_item for item 3
       post_items

Invocation of callbacks
-----------------------

   As you can see from the `unselected' and `selected' callbacks in the
above code, when a callback is invoked, it gets passed the
HTML::Navigation object as the first parameter, and the remaining
parameters form a hash which contains all the information you could
possibly need to know about the current item in order to generate suitable
output for it.  The keys for the hash include:

   * item

     The name of the current item, e.g. `item 2'.

   * level

     The depth of the current item in the navigation graph.  This will
     always be 0 until we progress to the multi-level examples below.

   * selected

     True iff the current item is selected.  Normally you won't need this
     because you know whether it's selected depending on whether the
     `selected' or `unselected' callback has been invoked, but you could
     use this to change the behaviour of the pre_item callback depending on
     whether the item is selected, for example.

   * leaf

     True iff the current item is a leaf in the navigation tree.  It will
     always be a leaf unless it's a submenu which is currently selected.

   * parent

     The name of the current item's parent.  This is `top' if we're at
     level 0 (which, as noted above, has always been the case in the
     examples so far).

   *You should not attempt to change any of the values in this hash.  If
you do so, you invalidate the module's warranty and no guarantees about
its behaviour can be made.*

More callback types
-------------------

   There are two more callback types to know about.  The first is
`item_glue', which is invoked in between each item:

     pre_items
       pre_item for item 1
       selected or unselected for item 1
       post_item for item 1

     item_glue

     pre_item for item 2
     selected or unselected for item 2
     post_item for item 2

     item_glue

     pre_item for item 3
     selected or unselected for item 3
     post_item for item 3
       post_items

   The second is `omit', which doesn't generate any output, but decides
whether a particular item should be included in or omitted from the
output.  Say that we used the following omit callback:

     sub {
       my ($nav, %p) = @_;
       return $p{item} eq 'item 2';
     }

   Then the callback order would be:

     pre_items
       pre_item for item 1
       selected or unselected for item 1
       post_item for item 1

     item_glue

     pre_item for item 3
     selected or unselected for item 3
     post_item for item 3
       post_items

__default__
-----------

   If we generate output for our single-level menu with no item selected
like so:

     $nav->output({});

   then the callback invocation order will be

     pre_items
       pre_item for item 1
       unselected for item 1
       post_item for item 1

     pre_item for item 2
     unselected for item 2
     post_item for item 2

     pre_item for item 3
     unselected for item 3
     post_item for item 3
       post_items

   so that no item appears selected.  But what if we always want an item
selected, even when the CGI parameter to select one is missing?  The
answer is to include __default__ in the structure:

     [
      __param__ => 'param',
      __callbacks__ => [ $level_0_callbacks ],
      __default__ => 'item 2',
      'item 1',
      'item 2',
      'item 3',
     ]

   Now if the CGI parameter `param' is missing, `item 2' will be selected.
If you want the default selected item to be the first item in the list,
but you don't necessarily know what the first item is called (see
`"Dynamically generating items"' in this node below) then set __default__
to the empty string.

Dynamically generating items
----------------------------

   If you want, you can dynamically build up the navigation structure at
output time by using coderefs:

     # Extract from eg/dynamic.cgi
     sub dynamic_items { [ 'item 2', 'item 3' ] }

     my $nav = new HTML::Navigation(base_url => 'simple.cgi');
     my $structure =
       [
        __param__ => 'param',
        __callbacks__ => [{
                           pre_items  => sub { "<ol>\n"  },
                           post_items => sub { "</ol>\n" },
                           pre_item   => sub { "  <li> " },
                           post_item  => sub { "\n"      },
                           unselected => sub {
                             my ($nav, %p) = @_;
                             return $nav->ahref(text => $p{item},
                                                params => [ $nav->params(%p) ]);
                           },
                           selected => sub {
                             my ($nav, %p) = @_;
                             return $p{item};
                           },
        'item 1',
        \&dynamic_items,
       ];

   `dynamic_items()' will be invoked during the call to output(), not
before.  This is mostly of use with multi-level navigation, for which see
below.

   You can use this "unpacking coderefs" technique to dynamically generate
as much of the contents of the containing arrayref as you want, i.e. even
the `__param__', `__callbacks__', and __default__ bits.

   You now know everything about single-level navigation!

Multi-level navigation
----------------------

   Again, this is best illustrated with an example of a two-level menu
(`eg/two-level.cgi').

     # Extract from eg/two-level.cgi
     [
      __param__ => 'first',
      __callbacks__ => [
                        # level 0
                        {
                         pre_items  => sub { "<ol>\n"  },
                         post_items => sub { "</ol>\n" },
                         pre_item   => sub { "<li> "   },
                         post_item  => sub { "\n"      },
                         unselected => sub {
                           my ($nav, %p) = @_;
                           return $nav->ahref(text => $p{item},
                                              params => [ $nav->params(%p) ]);
                         },
                         selected => sub {
                           my ($nav, %p) = @_;
                           return $p{item};
                         },
                        },

     # level 1
     {
      pre_items  => sub { "<ul>\n"  },
      post_items => sub { "</ul>\n" },
      pre_item   => sub { "<li> "   },
     },
                         ],
        'item 1' => [
                     __param__ => 'submenu_1',
                     'one',
                     'two',
                     'three',
                    ],
        'item 2',
        'item 3' => [
                     __param__ => 'submenu_2',
                     __default__ => 'five',
                     __callbacks__ => [{
                   pre_item  => sub { "<li> <b>" },
                   post_item => sub { " </b>\n"  },
                  }],
                     'four',
                     'five',
                     'six',
                     'seven',
                    ],
       ]

   This has a top-level menu as before, but now clicking on the first and
third items reveal further submenus containing `one' to `three', and
`four' to `seven' respectively.  Note the difference that __default__
creates between the two submenus: when you click on `item 1' it reveals
the first submenu but none of the sub-items are selected, whereas when you
click on `item 3' then `five' immediately gets selected.

   Also note how the callbacks are defined for the submenus (level 1).
Firstly the `pre_items', `post_items', `pre_item', `post_item',
`unselected', and `selected' callbacks are inherited from level 0.  Then
the `pre_items', `post_items', and `pre_item' callbacks are overriden by
the callbacks in the hashref following the `# level 1' comment.  Finally,
in the `item 3' submenu only, the `pre_item' and `post_item' callbacks are
overriden.  The net effect of all this is that both submenus are unordered
lists, and the items of the second submenu (`four' to `seven') are in bold.

   Finally, note that although in this example each submenu has a
different CGI parameter name determining selection within it (`submenu_1'
and `submenu_2'), everything would still work if they had the same CGI
parameter name (e.g. `submenu').

   Dynamic item generation works as before, except it is now potentially
much more useful, because if you have a submenu whose contains are
generated by a coderef which is an expensive operation (e.g. doing a
complex query on a database), then that expensive operation will only be
performed if the contents of that submenu are visible (i.e. iff the
submenu has been selected).

More complex navigation structures
----------------------------------

   All aspects of the navigation structure syntax have now been covered.
If you really want to, you could take a look at the multi-level structure
in `t/MyTest.pm', which contains some pathological features designed to
test the code to its limits.

BUGS / WISHLIST
===============

   Here are a few things aren't nice, and a few things which might be.
Suggestions and comments welcome.

   * The recursion code is convoluted and should be abstracted out.

   * The dump_all_params() stuff is a nasty hack, which I only included to
     make testing easier.

   * Some of the subroutines are way too long.  I tried breaking them up
     several times but always ended up with something even messier :-(

   * Maybe it would be cleaner to do output in two passes - one for parsing
     the navigation structure, and one for doing the output.  I'm guessing
     that most (all?) navigation structures won't be big enough to worry
     about the cost of doing two passes, but I could be wrong.

   * Recursion is currently depth-first only.

   * There needs to be a sanity check for duplicate `__param__' values at
     different levels.

   * Creation/manipulation/retrieval of specific bits of the navigation
     structure via methods, e.g.

          $nav->top->submenu('foo')->add_item('item under foo submenu');

     Maybe use Tree::DAG_Node?  This would mean some major changes though,
     as the structure is currently described as an arrayref, not a hashref,
     so as to preserve ordering.  If the structure parsing phase was
     separated out, that would make this a lot easier.

   * Optional tree-parsing during new() phase rather than during output()
     phase.  This has to be optional, because it would mean that any
     coderefs given to dynamically generate menu items would have to be run
     here, which is bad if your coderefs point to expensive code.

   * Debugging isn't tested.  But then that's kind of the point.

AUTHOR
======

   Adam Spiers <adam@spiers.net>


