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->{title} = 'Hello World';
      $self->{default_action} = 'hello';
    sub hello {
      my $self = shift || die 'need $self';
      return '<P>Yes, this is stupid.</P>';
    package main;

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.

: 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:

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

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