zenspider.com by ryan davis

Apache::ContentHandler is a generic object-oriented framework for creating mod_perl and CGI web applications. It provides a basic event mechanism and a subclassable framework for customizing actions and is highly suited to rapid prototyping of web applications.

Simple Example

package Apache::Hello;
use vars qw(@ISA);
use Apache::ContentHandler;
@ISA = 'Apache::ContentHandler';

sub handler {
  my $r = shift;
  my $app = new Apache::Hello($r);
  my $result = $app->run;
  return $result;
}

sub _init {
  my $self = shift || die 'need $self';
  $self->SUPER::_init(@_);
  $self->{title} = 'Hello World';
  $self->{default_action} = 'hello';
}

sub hello {
  my $self = shift || die 'need $self';
  return '<P>Yes, this is stupid.</P>';
}

package main;
Apache::Hello->new->run;

This shows a very simple example of what it can do. In this case, we set the default_action to ‘hello’, which is automatically executed. Hello in this case outputs a simple paragraph. Nothing big, but it is very simple. Note that this app runs as-is in both CGI and mod_perl.

Rapid Prototyping

This doesn’t demonstrate the real power of ContentHandler. The real power comes from rapid prototyping. For example, if we modifed the example above to read:

sub hello {
  my $self = shift || die 'need $self';

  return '<A HREF="$self->{url}?action=make">Make</A> something.';
}

Then the page will output a url for the application that includes “action=make” as a url parameter. This will tell ContentHandler to run the method make when executed. But, make doesn’t exist at this time. That’s ok, because ContentHandler will deal with it by putting a standard page up explaining that that feature isn’t yet implemented. This allows you to quickly prototype one page, and move on to the rest of the functionality one piece at a time.

I’ve used this style with clients on several different projects and they were all extremely happy to get something tangible in a very short period of time, usually 5 minutes to get the first page up and running with skeletal functionality. From there, it is a very interactive process with the client driving on one machine and commenting, and me coding away at another machine as they talk.

ContentHandler.pm API:

Public Methods:

$ch = Apache::ContentHandler->new
Creates a new ContentHandler. You should not override this, override _init instead.
$hc->run
The main application structure. Provides for a standard header, body, and footer. You probably do not want to override this, override the individual methods instead.

Protected Methods:

_init
Private: called by new. Override to put your application specific variables here.
$val = $self->arg($key)
Returns a CGI/mod_perl parameter for the key $key.
@keys = $self->args
Returns a list of all of the mod_perl/cgi parameters.
$s = $hc->_header
Returns a string containing the preheader, an HTML title, and a postheader. You probably do not want to override this unless you want a different type of title. This was renamed from header to _header to deal with CGI.
$s = $hc->work
Runs a method corresponding to the $action parameter, or the default action, and returns the content as the body of the document. If the $action does not exist, then it puts up a page stating that. This makes rapid prototyping very easy and quick.
$s = $hc->footer
Returns a string containing the prefooter, and postfooter. This used to have a standard footer as well, but I found it annoying.
$s = $hc->errors
Returns a dictionary list detailing the contents of the error hash, if any.
$s = $hc->preheader
Returns the contents of the preheader. Override to add something before the title.
$s = $hc->postheader
Returns the contents of the postheader. Override to add something after the title.
$s = $hc->prework
Returns the contents of the prework. Override to add something before the body.
$s = $hc->postwork
Returns the contents of the postwork. Override to add something after the body.
$s = $hc->prefooter
Returns the contents of the prefooter. Override to add something before the footer.
$s = $hc->postfooter
Returns the contents of the postfooter. Override to add something after the footer.
$s = $hc->reportError
Sends an email to the addresses listed in error_email, detailing an error with as much debugging content as possible. Used for fatal conditions.
$html .= $self->d(@args)
Simple debugging routine. Outputs the concatination of the args to STDERR and returns them as an HTML paragraph. Might be made more sophisticated someday, but not right now.

DBContentHandler.pm API:

DBContentHandler is a subclass of ContentHandler.

Protected Methods:

$s = $dbcgi->dbi
Returns a DBI connection. Override _init and add values for dbi_driver, dbi_user, and dbi_password to make this connection.
$s = $dbcgi->sqlToTable
Returns an HTML representation of a SQL statement in table form.
$s = $dbcgi->sqlToArrays
Returns a reference to an array of array references representing a SQL query.
$s = $dbcgi->sqlToArray
Returns a one-dimension array with the results of the query. This is usually used for selecting on a single column.
$s = $dbcgi->sqlToHashes
Returns a hash representing a SQL query.
$s = $dbcgi->query1
Returns a single value from a SQL query. The query must return a single column and row (ie SELECT name FROM users WHERE id=42).
my @cols = $dbcgi->cols
Returns an array of columns for a table with (hopefully) minimal overhead.
my $html = $dbcgi->sqlToPopup
Converts a two column select statment into an HTML popup menu. Expects the id to be the first column and the value or label to b e the second.
$dbcgi->sqlDo
Executes a SQL statement and returns nothing… Use this for updates and the like.
$s = $dbcgi->is_view($table_or_view_name)
Returns true if $table_or_view_name is a view in the database.
$s = $dbcgi->dbdetail
Creates a table with a detailed representation of a sql query.