The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache::Wyrd - HTML embeddable perl objects under mod_perl

SYNOPSIS

NONE

DESCRIPTION

Apache::Wyrd is the core module in a collection of interoperating modules that allow the rapid object-oriented development of web sites in Apache's mod_perl environment (LAMP). This collection includes a very flexible, HTML-friendly method of defining dynamic items on a web page, and interfacing directly to perl objects with them. It comes with many pre-built objects to support a web site such as an authentication module, an reverse-lookup database, granular debugging, and smart forms/inputs and their interfaces to a DBI-compliant SQL application.

The collection is not meant to be a drop-in replacement for PHP, ColdFusion, or other server-side parsed content creation systems, but to provide a more flexible framework for organic custom perl development for an experienced perl programmer who favors an object-oriented approach. It has been designed to simplify the transition from static to dynamic web content by allowing the design of objects that can be operated by a non-perl programmer through the modification of the HTML page on which the content is to be delivered.

The Apache::Wyrd module itself is an abstract class used to create HTML-embeddable perl objects (Wyrds). The embedded objects are interpreted from HTML files by an instance of the abstract class Apache::Wyrd::Handler. Most Wyrds also require an instance of an Apache::Wyrd::DBL object to store connection information and to provide intermediary access to the Apache request and any DBI-style database interfaces.

Each Wyrd has a corresponding perl module which performs work and generates any output at the Wyrd's location on the HTML page. Each of these objects is a derived class of Apache::Wyrd, and consequently draws on the existing methods of the abstract class as well as implements methods of its own. A few "hook" methods (_setup, _format_output, and _generate_output in particular) are defined in the abstract class for this purpose.

The modules in this distribution are not meant to be used directly. Instead, instances of the objects are created in another namespace (in all POD synopses called BASENAME, but it can be any string acceptable as a single namespace of a perl class) where the Handler object has been configured to use that namespace in interpreting HTML pages (see Apache::Wyrd::Handler).

SETUP

At the minimum, BASENAME::Wyrd needs to be defined, BASENAME::Handler needs to be defined and properly configured and able to properly invoke an instance of BASENAME::DBL. [N.B: A sample minimal installation, TESTCLIENT can be found in the t/lib directory of this package].

When a BASENAME::FOO Wyrd is invoked, and no BASENAME::FOO perl object can be found, the object Apache::Wyrd::FOO will be tried. This allows the use of any Apache::Wyrd::FOO objects derived from this module to be used in a web page as BASENAME::FOO objects without explicitly subclassing them. If neither a BASENAME::FOO nor an Apache::Wyrd::FOO object exists, a generic (do-nothing) Apache::Wyrd object will be used rather than an error occur.

As one would expect, one namespace can also instantiate another namespace's objects as long as the other namespace can be found in the local perl installation's @INC array.

SYNTAX IN HTML

Wyrds are embedded in HTML documents as if they were specialized tags. These tags are assigned attributes in a manner very similar to HTML tags, in that they are formed like HTML tags with named attributes and (optionally) with enclosed text, i.e.:

    <NAME ATTRIBUTENAME="ATTRIBUTE VALUE">ENCLOSED TEXT</NAME>

They follow the XHTML syntax somewhat in that they require a terminating whitespace followed by a forward-slash (/) before the enclosing brace when they are embedded as "stand-alone" tags, and require quotes around all attributes. Therefore:

    <BASENAME::WyrdName name=imasample>

must either be written:

    <BASENAME::WyrdName name="imasample"></BASENAME::WyrdName>

or as:

    <BASENAME::WyrdName name="imasample" />

to be valid. Invalid Wyrds are ignored and do not get processed, but may cause errors in other Wyrds if malformed, so it often pays to "view source" on your browser while debugging.

Unlike (X)HTML, however, Wyrds are named like perl modules with the double-colon syntax (BASENAME::SUBNAME::SUBSUBNAME) and these names are case-sensitive. Furthermore, either single or double quotes MUST be used around attributes, and these quotes must match on either side of the enclosed attribute value. Single quotes may be used, however, to enclose double quotes and vice-versa unless the entire attribute value is quoted. When in doubt, escape quotes by preceding them with a backslash (\). HTML tags should not appear inside attributes. See Apache::Wyrd::Template and Apache::Wyrd::Attribute for common ways around this limitation.

Also unlike (X)HTML, one Wyrd of one type cannot be embedded in another of the same type. We believe this is a feature(TM).

LIFE CYCLE

The "normal" behavior of a Wyrd is simply to disappear, leaving its enclosed text behind after interpreting all the Wyrds within that text. It is through "hook" methods that manipulation and output of perl-generated material is accomplished.

Just as nested HTML elements produce different outcomes on a web page depending on the order which they are nested in, Wyrds are processed relative to their nesting. The outermost Wyrd is created (with the new method) first from a requested page and processes its enclosed text, spawning the next enclosing tag within it, and so on. When the final nested Wyrd is reached, that Wyrd's output method is called and the resulting text replaces it on the page. The output method of each superclosing tag is called in turn, repeating the process. Between new and output are several stages. In these stages, "hooks" for Wyrd specialization are called:

  1. new calls _setup which allows initialization of the Wyrd before it processes itself, spawning enclosed Wyrds.

  2. _setup returns the object, which waits for the output call to be performed on it by it's parent or by the Handler.

  3. When the output method is called, it processes itself, meaning that it goes through the enclosed text (if any), finding embedded Wyrds. When such a Wyrd is found, it spawns a new object based on itself, inheriting the same Apache::Wyrd::DBL, the same Apache request object, the same loglevel (see attributes, below), and so on. Prior to spawning, the hook method _pre_spawn is called to allow changes to the new Wyrd before it is created.

  4. output then calls the two hooks, _format_output which is meant to handle changes to the enclosing text and _generate_output which returns the actual text to replace the Wyrd at that point in the HTML page.

In most cases, there will not be any need to override non-hook methods. For minor variations on Wyrd behavior, most of the built-in Wyrds can be quickly extended by overriding the method with a method that calls the SUPER class:

  sub _setup {
    my $self = shift;
    
    ...do something here...
    
    return $self->SUPER::_setup();
  }

HTML ATTRIBUTES

Any legal attribute can generally be used. Some, however, are important and are be reserved.

RESERVED ATTRIBUTES

loglevel

A value, defining the degree to which the Wyrd will spew debugging information into STDERR (normally the Apache error log). You may use the keywords fatal, error, warn, info, debug, and verbose or their corresponding numerical value (0-5).

dielevel

The degree of error which will trigger a server error. Corresponds to the loglevels and defaults to 'fatal'.

flags

A list of optional modifiers, separated by whitespace or commas, which can be used to modify the behavior of the Wyrd. Flags should contain no whitespace. One builtin flag exists: disable keeps the Wyrd and all enclosed data from being processed or generated at all.

Additionally, any attributes corresponding to the reserved public methods below will be discarded.

PRIVATE ATTRIBUTES

    Any attribute beginning with an underline is reserved for future development. Two of these are created at the time of generation which are particularly important and deserve mention:

    _data

    At the time of spawning a new Wyrd, the enclosed text is stored in the attribute _data. This attribute is the data processed during the first phase of the output method, and is available to the hook methods. If one hook method changes this value, however, it is important that the other hooks take this into account. The default _generate_output simply returns this value, for example.

    _flags

    Also at the time of spawning, the flags attribute is translated into an Apache::Wyrd::Services::Tree object. This object is used to keep track of whether a flag is set or not, for example:

        $self->_flags->reverse;

    will return the value "1" if the flags attribute contains the flag token "reverse", and undef if it does not. Flags can be (un)set by providing the appropriate argument, for example:

        $self->_flags->reverse(0);

PERL METHODS

Unlike most perl modules, modules derived from Apache::Wyrd attempt to leave public methods open to the developer so that they can appear as attributes in the corresponding HTML. Hence, most important Wyrd methods are private and are denoted as such by a leading underscore (_). Some methods are public, usually for obvious or traditional reasons.

PUBLIC METHODS

In most cases, a given HTML attribute will be available to the Wyrd directly by accessing $self->{attribute}. For convenience, these can be accessed via a method call to the name of the attribute (example: $value = $self->attributename). If the method call has an argument, it means to set rather than retrieve the attribute (example: $self->attributename($value)).

Important Documentation Note: Since the paragraph above describes the default behavior for attributes, a perl method is not described in the POD for these modules for any attributes UNLESS the method has been explicitly defined, for example, to make the attribute read-only or be a value other than scalar.

Note: methods are described (format: (returned value/s) methodname (arguments)), where the first argument, representing the object itself, is assumed, since the method is called using the standard notation $object->method.

(Apache::Wyrd ref) new (Apache::Wyrd::DBL ref, hashref)

create and return a Wyrd object

(Apache::Wyrd ref) clone (void)

make an identical copy of this Wyrd

(Apache::Wyrd::DBL ref) dbl (void)

the current DBL

(scalar) class_name (void)

The full name of this Wyrd.

(scalar) base_class (void)

The BASENAME of the currently executing installation of Apache::Wyrd.

(scalar) output (void)

produce the text this Wyrd is meant to produce.

(void) abort (Apache::Constant response code)

End all processing and return a response code with no output. Defaults to Apache::Constants::SERVER_ERROR.

(void) abort_redirect (scalar location)

End the processing of the page this wyrd is on and redirect to another. The redirection is an internal one, so the location argument must be another page on the same site, with an absolute pathname.

HOOK METHODS

(void) _setup (void)

Set-up the Wyrd before processing enclosed "child" Wyrds. Useful in particular for setting up data structures the child Wyrds will refer to.

(scalar) _format_output (void)

Format/change any enclosed text. The main hook for Wyrd processing. Generally should be confined to preparing for and performing the modification of and the _data attribute.

(scalar) _generate_output (void)

Return the resulting text from the Wyrd, finishing all processing. Generally used when the output should return something other than the _data attribute.

(scalar) _shutdown (void)

Do any last-minute housekeeping, such as closing database connections, filehandles.

(scalar, hashref) _pre_spawn (scalar classname, hashref initialization)

Pre-spawn allows the classname or initialization hash to be modified before a child Wyrd is generated.

(scalar) _generate_xxx (scalar)

If the method _generate_xxx is called where xxx is an HTML tagname and no such method is defined, the Wyrd will attempt to return the value given enclosed by tags of the type xxx:

        <xxx>given value</xxx>

This behavior has proven of limited value and is depreciated.

(void) _fatal/_error/_warn/_info/_debug/_verbose (scalar)

These methods all log an error at the given loglevel. See Apache::Wyrd::Handler for a discussion of loglevels and their affect on Apache.

OTHER RESERVED METHODS

The methods _init, _process_self, _spawn, _process_flags, and _return_object are also reserved and provide the "natural" behavior for Apache::Wyrd objects. No documentation of them is provided, as they are not meant to be modified. Please contact the author if you feel some documentation is needed.

BUGS/CAVEATS

FREE SOFTWARE

Apache::Wyrd 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 any later version.

Apache::Wyrd 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.

(GENERALLY) UNIX-Only

This software has only tested under Linux and Darwin, but should work for any *nix-style system. This software is not intended for use on windows or other delicate glassware.

Cross Scripting

This software is meant to run on mod_perl, which, unlike PHP for example, is not a separate language. It is a direct interface to Apache internals. Although Apache::Wyrd supports multiple namespaces and consequently, multiple sites on different virtual server definitions of an Apache installation, it has not, and the author believes cannot, be designed to prevent cross-scripting attacks. Consequently, Apache::Wyrd is not appropriate for a shared hosting environment where different site contributors must be protected from each other.

AUTHOR

Barry King <wyrd@nospam.wyrdwright.com>

SEE ALSO

A few modules provide some of the basic services of the Library. They often have, and list in their SEE ALSO sections, the modules which support them.

Apache::Wyrd::Handler, Apache::Wyrd::DBL

For information on setting up the Apache::Wyrd abstract classes

Apache::Wyrd::Form

For information on smart form processing

Apache::Wyrd::Services::Auth

For information on the built-in authorization system

Apache::Wyrd::Services::Index

For information on the reverse-key indexing engine

Apache::Wyrd::Services::Debug

For information on the debugging sub-system

Apache::Wyrd::Services::SAK

The "swiss army knife" of useful methods/subroutines which are collected in one library to improve standardization of behaviors.

Apache::Wyrd::Site

A collection of inter-related Wyrds which can be used to quickly implement an integrated site with self-maintaining navigation, search engine, subject cross-references, publication management, and dynamic state-tracked elements.

LICENSE

Copyright 2002-2007 Wyrdwright, Inc. and licensed under the GNU GPL.

You should have received a copy of the GNU General Public License along with Apache::Wyrd (see LICENSE); if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

5 POD Errors

The following errors were encountered while parsing the POD:

Around line 301:

You can't have =items (as at line 307) unless the first thing after the =over is an =item

Around line 557:

You forgot a '=back' before '=head3'

Around line 559:

'=item' outside of any '=over'

Around line 637:

'=item' outside of any '=over'

Around line 667:

You forgot a '=back' before '=head3'