CGI::Application
Item description : Framework for building reusable web-applications in an object-orientated and extensible fashion
Review Synopsis : An excellent and well-thought out module implementing powerful and downright easy methods to write and build CGI-based applications.
Why use CGI::Application?
The
CGI::Application module implements this object-orientated framework within which to build your application by creating a super-class within which specific 'run-modes' can be defined. Each run-mode can be correlated to a particular stage of the HTML/CGI user interface. Furthermore, the
CGI::Application module implements methods to address the
CGI.pm and
HTML::Template modules, facilitating powerful methods by which to build extensible and portable web applications - It is obvious that the module author, Jesse Erlbaum (jesse at vm dot com), has put a lot of work into the development and writing of this module.
This module allows you to do away with ugly code through the combination of
CGI.pm,
HTML::Template and methods provided by
CGI::Application to implement persistent variables across execution states.
(Part of the reason too as to my personal usage of this module is its integration with my preferred templating framework,
HTML::Template - Different web application frameworks were reviewed by
princepawn at
Web Application Frameworks and their Templating Engines with a Comparative Study of Template and HTML::Template)
Why avoid CGI::Application?
There seems to be few reasons why to avoid using the
CGI::Application module - Usage may not be necessary if persistence and state methods are implemented with other frameworks such as
Apache::Session,
HTML::Mason or
HTML::Embperl.
How to use CGI::Application?
The documentation for the
CGI::Application module is excellent and covers the building of a (theoretical) database search application. In short, this module promotes the building of applications as self-styled modules based on the
CGI::Application framework - The end script (application) consists of an instance script and a module package.
An example instance script may look like this:
#!/usr/bin/perl
# Use our self-styled application module built on the CGI::Applicati
+on framework
#
use self;
# Create constructor for our application module (self->new()) and ex
+ecute this module in the desired run mode (self->run()) - The desired
+ run mode is set via the value of a CGI parameter specified by the mo
+de_param() method of this module (see self-styled CGI::Application mo
+dule package).
#
my ($application) = self->new();
$application->run();
exit 0;
The corresponding module (self) based on the
CGI::Application framework may look like this:
package self;
sub setup {
my ($self) = shift;
# Set the CGI parameter from which the run-mode of the applicati
+on is derived to be 'stage' - This method allows you to set your own
+run-mode specifier, passed to your CGI script via hidden HTML form in
+put tags
#
$self->mode_param('stage');
# Set the matched run-mode / subroutine functions to determine w
+hich function should be executed for a given run-mode - This method i
+s that which allows reusable code to be easily implemented for separa
+te run-mode.
#
# In this example, the subroutines 'display_form' and 'display_r
+esults' have been specified to run for run-modes '1' and '2' respecti
+vely. The subroutines can be defined as either a hard reference to t
+he run-mode method or the name of the run-mode method to be called.
#
$self->run_modes({
'1' => \&display_form,
'2' => 'display_results',
});
# Set the mode which should be run in the first instance of the
+script, where no run-mode may be specified by a passed CGI variable -
+ By default, this mode is called 'start', which too must be reference
+d to a subroutine via the run_modes() method.
#
$self->start_mode('1');
};
1;
This is a very basic example of the totality of module framework required to implement the
CGI::Application framework - The example above is lacking the referenced subroutines display_form and display_results but provides a clear example of HOW the module framework works.
Additional methods within the
CGI::Application framework include:
-
param()
- This method allows to create parameter references which can be referenced across all module/application run modes - This method is most obviously used in the setup() method to implement such references such as DBI connections, HTML::FormValidator schema, etc. eg.
sub setup {
my ($self) = shift;
$self->mode_param('stage');
$self->run_modes({
'1' => \&display_form,
'2' => 'display_results',
});
$self->start_mode('1');
# Create DBI connection handle and make accessible to all run-mo
+des via CGI::Application param() method
#
$self->param('dbh' => DBI->connect());
};
teardown()
- The paired partner of setup(), this method is implemented automatically after the application is run and can be used for clean up persistent variable and database connections. eg.
sub teardown {
my ($self) = shift;
# Disconnect the (persistent, with Apache::DBI) DBI handle creat
+ed in setup() and passed via the param() method
#
$self->param('dbh')->disconnect;
};
query()
- This method retrieves the CGI.pm object (CGI->new()) created with the instance of your self-styled CGI::Application module. All methods for CGI.pm can be applied to the blessed reference returned.
load_tmpl()
- This method creates a HTML::Template object (HTML::Template->new()), allowing HTML templates to be employed, aiding in the pyrrhic (depending on your viewpoint) goal of separating code and design. All methods for HTML::Template can be applied to the blessed reference returned.
Tips and Gotchas for CGI::Application
The primary note made about run-mode methods in the
CGI::Application documentation is to avoid printing directly to STDOUT, instead returning the HTML output (
$html->output, if $html is a
HTML::Template blessed reference created via
load_tmpl()) at the end of the run-mode subroutine to the
CGI::Application framework.
For example:
# An example run-mode method
#
sub display_page {
my ($self) = shift;
# Create a HTML::Template blessed reference with the template fi
+le, page.html
#
my ($html) = $self->load_tmpl('page.html');
print STDOUT $html->output; # printing template output direc
+tly to STDOUT (*BAD*)
return $html->output; # return template output to CGI:
+:Application framework for display (*GOOD*)
};
With the handling of HTML output to STDOUT by the
CGI::Application framework rather than within the run-mode subroutine itself, header types and properties should also not be directly manipulated via CGI methods within run-mode methods. Instead, the
CGI::Application framework provides two methods for handling header types and properties indirectly - These methods are described below:
-
header_type(<'header' || 'redirect'>)
- This method specifies the type of HTTP headers which should be sent back to the client browser by the CGI::Application framework.
header_props()
- This method specifies the HTTP header properties which should be sent back to the client browser by the CGI::Application framework - This method correlates to the header() (and redirect()) methods of the CGI.pm module.
Another tip in the documentation of
CGI::Application is the definition the run-mode '
AUTOLOAD' - This run-mode is evoked if the
mode_param() CGI parameter calls a run-mode definition not matched to a package subroutine via
run_modes() method. This allows the the implementation of 'user-friendly' error pages rather than the default
CGI::Application behaviour to
croak() on such errors. If evoked, the name of the intended run-mode passed via the
mode_param() CGI parameter is passed to the
AUTOLOAD run-mode as an argument.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.