CGI::Application - Framework for building reusable web-applications
| Use Case | Command | Description |
|---|---|---|
| Create a new application module | package WebApp; use base 'CGI::Application'; | Define a new CGI::Application subclass |
| Define run modes and start mode | $self->start_mode('mode1'); $self->run_modes(...) | Set up the application's dispatch table in setup() |
| Run the application as CGI | my $app = WebApp->new(); $app->run(); | Instance script execution |
| Run as PSGI application | WebApp->psgi_app(); | Return a PSGI-compatible coderef |
| Load a template | $self->load_tmpl('page.html') | Load an HTML::Template object |
| Set HTTP headers | $self->header_props(-type => 'text/html') | Modify outgoing HTTP headers |
| Redirect | $self->header_type('redirect'); $self->header_props(-url => '...') | Perform an HTTP redirect |
| Set custom parameters | $self->param('key', 'value') | Store/retrieve application instance data |
| Get CGI query object | my $q = $self->query() | Access the CGI.pm query object |
| Use PATH_INFO for run mode | $self->mode_param(path_info => 1) | Clean URIs without query string |
| Error handling | $self->error_mode('my_error_rm') | Define a fallback run mode on die() |
| Testing | $ENV{CGI_APP_RETURN_ONLY}=1; my $out = $app->run(); | Suppress output for testing |
# In "WebApp.pm"...
package WebApp;
use base 'CGI::Application';
# ( setup() can even be skipped for common cases. See docs below. )
sub setup {
my $self = shift;
$self->start_mode('mode1');
$self->mode_param('rm');
$self->run_modes(
'mode1' => 'do_stuff',
'mode2' => 'do_more_stuff',
'mode3' => 'do_something_else'
);
}
sub do_stuff { ... }
sub do_more_stuff { ... }
sub do_something_else { ... }
1;
### In "webapp.cgi"...
use WebApp;
my $webapp = WebApp->new();
$webapp->run();
### Or, in a PSGI file, webapp.psgi
use WebApp;
WebApp->psgi_app();
CGI::Application makes it easier to create sophisticated, high-performance, reusable web-based applications. It helps make your web applications easier to design, write, and evolve.
CGI::Application judiciously avoids employing technologies and techniques which would bind a developer to any one set of tools, operating system or web server.
It is lightweight in terms of memory usage, making it suitable for common CGI environments, and a high performance choice in persistent environments like FastCGI or mod_perl.
By adding PLUG-INS as your needs grow, you can add advanced and complex features when you need them.
First released in 2000 and used and expanded by a number of professional website developers, CGI::Application is a stable, reliable choice.
Imagine you have to write an application to search through a database of widgets. Your application has three screens:
To write this application using CGI::Application you will create two files:
#!/usr/bin/perl -w
use WidgetView;
my $webapp = WidgetView->new();
$webapp->run();
package WidgetView;
use base 'CGI::Application';
use strict;
# Needed for our database connection
use CGI::Application::Plugin::DBH;
sub setup {
my $self = shift;
$self->start_mode('mode1');
$self->run_modes(
'mode1' => 'showform',
'mode2' => 'showlist',
'mode3' => 'showdetail'
);
# Connect to DBI database, with the same args as DBI->connect();
$self->dbh_config();
}
sub teardown {
my $self = shift;
# Disconnect when we're done, (Although DBI usually does this automatically)
$self->dbh->disconnect();
}
sub showform {
my $self = shift;
# Get CGI query object
my $q = $self->query();
my $output = '';
$output .= $q->start_html(-title => 'Widget Search Form');
$output .= $q->start_form();
$output .= $q->textfield(-name => 'widgetcode');
$output .= $q->hidden(-name => 'rm', -value => 'mode2');
$output .= $q->submit();
$output .= $q->end_form();
$output .= $q->end_html();
return $output;
}
sub showlist {
my $self = shift;
# Get our database connection
my $dbh = $self->dbh();
# Get CGI query object
my $q = $self->query();
my $widgetcode = $q->param("widgetcode");
my $output = '';
$output .= $q->start_html(-title => 'List of Matching Widgets');
## Do a bunch of stuff to select "widgets" from a DBI-connected
## database which match the user-supplied value of "widgetcode"
## which has been supplied from the previous HTML form via a
## CGI.pm query object.
##
## Each row will contain a link to a "Widget Detail" which
## provides an anchor tag, as follows:
##
## "widgetview.cgi?rm=mode3&widgetid=XXX"
##
## ...Where "XXX" is a unique value referencing the ID of
## the particular "widget" upon which the user has clicked.
$output .= $q->end_html();
return $output;
}
sub showdetail {
my $self = shift;
# Get our database connection
my $dbh = $self->dbh();
# Get CGI query object
my $q = $self->query();
my $widgetid = $q->param("widgetid");
my $output = '';
$output .= $q->start_html(-title => 'Widget Detail');
## Do a bunch of things to select all the properties of
## the particular "widget" upon which the user has
## clicked. The key id value of this widget is provided
## via the "widgetid" property, accessed via the CGI.pm
## query object.
$output .= $q->end_html();
return $output;
}
1; # Perl requires this at the end of all modules
CGI::Application takes care of implementing the new() and the run() methods. Notice that at no point do you call print() to send any output to STDOUT. Instead, all output is returned as a scalar.
CGI::Application's most significant contribution is in managing the application state. Notice that all which is needed to push the application forward is to set the value of a HTML form parameter 'rm' to the value of the "run mode" you wish to handle the form submission.
The guiding philosophy behind CGI::Application is that a web-based application can be organized into a specific set of "Run Modes." Each Run Mode is roughly analogous to a single screen (a form, some output, etc.). All the Run Modes are managed by a single "Application Module" which is a Perl module. In your web server's document space there is an "Instance Script" which is called by the web server as a CGI (or an Apache::Registry script if you're using Apache + mod_perl).
This methodology is an inversion of the "Embedded" philosophy (ASP, JSP, EmbPerl, Mason, etc.) in which there are "pages" for each state of the application, and the page drives functionality. In CGI::Application, form follows function โ the Application Module drives pages, and the code for a single application is in one place; not spread out over multiple "pages".
Apache is NOT a requirement for CGI::Application. Web applications based on CGI::Application will run equally well on NT/IIS or any other CGI-compatible environment. CGI::Application-based projects are, however, ripe for use on Apache/mod_perl servers, as they naturally encourage Good Programming Practices and will often work in persistent environments without modification.
It is intended that your Application Module will be implemented as a sub-class of CGI::Application. This is done simply as follows:
package My::App;
use base 'CGI::Application';
By inheriting from CGI::Application you have access to a number of built-in methods. The following are those which are expected to be called from your Instance Script.
new()The new() method is the constructor for a CGI::Application. It returns a blessed reference to your Application Module package (class). Optionally, new() may take a set of parameters as key => value pairs:
my $webapp = WebApp->new(
TMPL_PATH => 'App/',
PARAMS => {
'custom_thing_1' => 'some val',
'another_custom_thing' => [qw/123 456/]
}
);
This method may take some specific parameters:
load_tmpl(). Can be a scalar or an array reference of multiple paths.One common use of instance scripts is to provide a path to a config file. Here's an example using CGI::Application::Plugin::ConfigAuto:
my $app = WebApp->new(PARAMS => { cfg_file => 'config.pl' });
# Later in your app:
my %cfg = $self->cfg()
# or ... $self->cfg('HTML_ROOT_DIR');
run()The run() method is called upon your Application Module object, from your Instance Script. When called, it executes the functionality in your Application Module.
my $webapp = WebApp->new();
$webapp->run();
This method first determines the application state by looking at the value of the CGI parameter specified by mode_param() (defaults to 'rm' for "Run Mode"), which is expected to contain the name of the mode of operation. If not specified, the state defaults to the value of start_mode().
Once the mode has been determined, run() looks at the dispatch table stored in run_modes() and finds the function pointer which is keyed from the mode name. If found, the function is called and the data returned is print()'ed to STDOUT and to the browser. If the specified mode is not found in the run_modes() table, run() will croak().
CGI::Application offers native PSGI support. The default query object for this is CGI::PSGI, which simply wrappers CGI.pm to provide PSGI support to it.
psgi_app()$psgi_coderef = WebApp->psgi_app({ ... args to new() ... });
The simplest way to create and return a PSGI-compatible coderef. Pass in arguments to a hashref just as to new(). This returns a PSGI-compatible coderef, using CGI::PSGI as the query object.
run_as_psgi()my $psgi_aref = $webapp->run_as_psgi;
Just like run(), but prints no output and returns the data structure required by the PSGI specification. Use this if you want to run the application on top of a PSGI-compatible handler, such as Plack provides.
The structure returned is an arrayref, containing the status code, an arrayref of header key/values and an arrayref containing the body.
[ 200, [ 'Content-Type' => 'text/html' ], [ $body ] ]
The final result might look like this:
use WebApp;
use CGI::PSGI;
my $handler = sub {
my $env = shift;
my $webapp = WebApp->new({ QUERY => CGI::PSGI->new($env) });
$webapp->run_as_psgi;
};
Have your run mode return a file handle or compatible subref as follows:
sub returning_a_file_handle {
my $self = shift;
$self->header_props(-type => 'text/plain');
open my $fh, "<", 'test_file.txt' or die "OOPS! $!";
return $fh;
}
sub returning_a_subref {
my $self = shift;
$self->header_props(-type => 'text/plain');
return sub {
my $writer = shift;
foreach my $i (1..10) {
#sleep 1;
$writer->write("check $i: " . time . "\n");
}
};
}
CGI::Application implements some methods which are expected to be overridden by implementing them in your sub-class module.
setup()This method is called by the inherited new() constructor method. The setup() method should be used to define the following property/methods:
mode_param() โ set the name of the run mode CGI param.start_mode() โ text scalar containing the default run mode.error_mode() โ text scalar containing the error mode.run_modes() โ hash table containing mode => function mappings.tmpl_path() โ text scalar or array reference containing path(s) to template files.Your setup() method might be implemented something like this:
sub setup {
my $self = shift;
$self->tmpl_path('/path/to/my/templates/');
$self->start_mode('putform');
$self->error_mode('my_error_rm');
$self->run_modes({
'putform' => 'my_putform_func',
'postdata' => 'my_data_func'
});
$self->param('myprop1');
$self->param('myprop2', 'prop2value');
$self->param('myprop3', ['p3v1', 'p3v2', 'p3v3']);
}
However, often times all that needs to be in setup() is defining your run modes and your start mode. CGI::Application::Plugin::AutoRunmode allows you to do this with a simple syntax, using run mode attributes:
use CGI::Application::Plugin::AutoRunmode;
sub show_first : StartRunmode { ... };
sub do_next : Runmode { ... }
teardown()If implemented, this method is called automatically after your application runs. It can be used to clean up after your operations. A typical use of the teardown() function is to disconnect a database connection which was established in the setup() function.
cgiapp_init()If implemented, this method is called automatically right before the setup() method is called. This method provides an optional initialization hook, which improves the object-oriented characteristics of CGI::Application. The cgiapp_init() method receives, as its parameters, all the arguments which were sent to the new() method.
An example of creating a custom "application super-class":
# In MySuperclass.pm:
package MySuperclass;
use base 'CGI::Application';
sub cgiapp_init {
my $self = shift;
# Perform some project-specific init behavior
# such as to load settings from a database or file.
}
# In MyApplication.pm:
package MyApplication;
use base 'MySuperclass';
sub setup { ... }
sub teardown { ... }
# The rest of your CGI::Application-based follows...
cgiapp_prerun()If implemented, this method is called automatically right before the selected run mode method is called. This method provides an optional pre-runmode hook, which permits functionality to be added at the point right before the run mode method is called. The value of the run mode is passed into cgiapp_prerun().
It is also possible, within your cgiapp_prerun() method, to change the run mode of your application. This can be done via the prerun_mode() method.
cgiapp_postrun()If implemented, this hook will be called after the run mode method has returned its output, but before HTTP headers are generated. This will give you an opportunity to modify the body and headers before they are returned to the web browser.
A typical use for this hook is pipelining the output through a series of "filter" processors. A typical implementation:
sub cgiapp_postrun {
my $self = shift;
my $output_ref = shift;
# Enclose output HTML table
my $new_output = "<table border=1>";
$new_output .= "<tr><td> Hello, World! </td></tr>";
$new_output .= "<tr><td>". $$output_ref ."</td></tr>";
$new_output .= "</table>";
# Replace old output with new output
$$output_ref = $new_output;
}
cgiapp_get_query()my $q = $webapp->cgiapp_get_query;
Override this method to retrieve the query object if you wish to use a different query interface instead of CGI.pm. CGI.pm is only loaded if it is used on a given request.
The following methods are inherited from CGI::Application, and are available to be called by your application within your Application Module.
load_tmpl()my $tmpl_obj = $webapp->load_tmpl;
my $tmpl_obj = $webapp->load_tmpl('some.html');
my $tmpl_obj = $webapp->load_tmpl( \$template_content );
my $tmpl_obj = $webapp->load_tmpl( FILEHANDLE );
This method takes the name of a template file, a reference to template data or a FILEHANDLE and returns an HTML::Template object. If the filename is undefined or missing, CGI::Application will default to trying to use the current run mode name, plus the extension ".html".
When you pass in a filename, the HTML::Template->new_file() constructor is used. When you pass in a reference to the template content, the HTML::Template->new_scalar_ref() constructor is used and when you pass in a filehandle, the HTML::Template->new_filehandle() constructor is used.
The load_tmpl() method will pass any extra parameters sent to it directly to HTML::Template->new_file() (or new_scalar_ref() or new_filehandle()):
my $tmpl_obj = $webapp->load_tmpl('some_other.html',
die_on_bad_params => 0,
cache => 1
);
Note that if you want to pass extra arguments but use the default template name, you still need to provide a name of "undef":
my $tmpl_obj = $webapp->load_tmpl(undef,
die_on_bad_params => 0,
cache => 1
);
html_tmpl_class()You may specify an API-compatible alternative to HTML::Template by setting a new html_tmpl_class():
$self->html_tmpl_class('HTML::Template::Dumper');
The default is "HTML::Template". The alternate class should provide at least the following parts of the HTML::Template API:
$t = $class->new( scalarref => ... ); # If you use scalarref templates
$t = $class->new( filehandle => ... ); # If you use filehandle templates
$t = $class->new( filename => ... );
$t->param(...);
Here's an example case allowing you to precisely test what's sent to your templates:
$ENV{CGI_APP_RETURN_ONLY} = 1;
my $webapp = WebApp->new;
$webapp->html_tmpl_class('HTML::Template::Dumper');
my $out_str = $webapp->run;
my $tmpl_href = eval "$out_str";
# Now Precisely test what would be set to the template
is ($tmpl_href->{pet_name}, 'Daisy', "Daisy is sent template");
load_tmpl() callbackPlugin authors will be interested to know that you can register a callback that will be executed just before load_tmpl() returns:
$self->add_callback('load_tmpl',\&your_method);
When your_method() is executed, it will be passed three arguments:
load_tmplHere's an example stub for a load_tmpl() callback:
sub my_load_tmpl_callback {
my ($c, $ht_params, $tmpl_params, $tmpl_file) = @_
# modify $ht_params or $tmpl_params by reference...
}
param()$webapp->param('pname', $somevalue);
The param() method provides a facility through which you may set application instance properties which are accessible throughout your application.
The param() method may be used in two basic ways. First, you may use it to get or set the value of a parameter:
$webapp->param('scalar_param', '123');
my $scalar_param_values = $webapp->param('some_param');
Second, when called in the context of an array, with no parameter name specified, param() returns an array containing all the parameters which currently exist:
my @all_params = $webapp->param();
The param() method also allows you to set a bunch of parameters at once by passing in a hash (or hashref):
$webapp->param(
'key1' => 'val1',
'key2' => 'val2',
'key3' => 'val3',
);
query()my $q = $webapp->query();
my $remote_user = $q->remote_user();
This method retrieves the CGI.pm query object which has been created by instantiating your Application Module. When the new() method is called, a CGI query object is automatically created. If, for some reason, you want to use your own CGI query object, the new() method supports passing in your existing query object on construction using the QUERY attribute.
You can also pass a query object to query() after construction:
$webapp->query($new_query_object);
my $q = $webapp->query(); # now uses $new_query_object
run_modes()# The common usage: an arrayref of run mode names that exactly match subroutine names
$webapp->run_modes([qw/
form_display
form_process
/]);
# With a hashref, use a different name or a code ref
$webapp->run_modes(
'mode1' => 'some_sub_by_name',
'mode2' => \&some_other_sub_by_ref
);
This accessor/mutator specifies the dispatch table for the application states. It returns the dispatch table as a hash. The run_modes() method may be called more than once. Additional values passed into run_modes() will be added to the run modes table.
The run() method uses the data in this table to send the application to the correct function as determined by reading the CGI parameter specified by mode_param() (defaults to 'rm' for "Run Mode").
The run mode method specified is expected to return a block of text (e.g.: HTML) which will eventually be sent back to the web browser. The run mode method may return its block of text as a scalar or a scalar-ref.
Specifying the run modes by array reference:
$webapp->run_modes([ 'mode1', 'mode2', 'mode3' ]);
This is the same as using a hash, with keys equal to values:
$webapp->run_modes(
'mode1' => 'mode1',
'mode2' => 'mode2',
'mode3' => 'mode3'
);
If CGI::Application is asked to go to a run mode which doesn't exist it will usually croak() with errors. If this is not your desired behavior, it is possible to catch this exception by implementing a run mode with the reserved name "AUTOLOAD":
$self->run_modes(
"AUTOLOAD" => \&catch_my_exception
);
If specified, this run mode will be invoked just like a regular run mode, with one exception: It will receive, as an argument, the name of the run mode which invoked it:
sub catch_my_exception {
my $self = shift;
my $intended_runmode = shift;
my $output = "Looking for '$intended_runmode', but found 'AUTOLOAD' instead";
return $output;
}
start_mode()$webapp->start_mode('mode1');
The start_mode contains the name of the mode as specified in the run_modes() table. Default mode is "start". The mode key specified here will be used whenever the value of the CGI form parameter specified by mode_param() is not defined. Generally, this is the first time your application is executed.
tmpl_path()$webapp->tmpl_path('/path/to/some/templates/');
This access/mutator method sets the file path to the directory (or directories) where the templates are stored. It is used by load_tmpl() to find the template files, using HTML::Template's "path" option. To set the path you can either pass in a text scalar or an array reference of multiple paths.
You can skip this section if you are just getting started.
delete()$webapp->delete('my_param');
The delete() method is used to delete a parameter that was previously stored inside of your application either by using the PARAMS hash that was passed in your call to new() or by a call to the param() method.
dump()print STDERR $webapp->dump();
The dump() method is a debugging function which will return a chunk of text which contains all the environment and web form data of the request, formatted nicely for human readability. Useful for outputting to STDERR.
dump_html()my $output = $webapp->dump_html();
The dump_html() method is a debugging function which will return a chunk of text which contains all the environment and web form data of the request, formatted nicely for human readability via a web browser.
error_mode()$webapp->error_mode('my_error_rm');
If the runmode dies for whatever reason, run() will see if you have set a value for error_mode(). If you have, run() will call that method as a run mode, passing $@ as the only parameter. No "error_mode" is defined by default.
get_current_runmode()$webapp->get_current_runmode();
The get_current_runmode() method will return a text scalar containing the name of the run mode which is currently being executed. If the run mode has not yet been determined, such as during setup(), this method will return undef.
header_add()# add or replace the 'type' header
$webapp->header_add( -type => 'image/png' );
# add an additional cookie
$webapp->header_add(-cookie=>[$extra_cookie]);
The header_add() method is used to add one or more headers to the outgoing response headers. Unlike calling header_props(), header_add() will preserve any existing headers. If a scalar value is passed to header_add() it will replace the existing value for that key. If an array reference is passed as a value to header_add(), values in that array ref will be appended to any existing values for that key.
header_props()# Set a complete set of headers
%set_headers = $webapp->header_props(-type=>'image/gif',-expires=>'+3d');
# clobber / reset all headers
%set_headers = $webapp->header_props({});
# Just retrieve the headers
%set_headers = $webapp->header_props();
The header_props() method expects a hash of CGI.pm-compatible HTTP header properties. These properties will be passed directly to the header() or redirect() methods of the query() object. Calling header_props() with an empty hashref clobbers any existing headers.
header_type()$webapp->header_type('redirect');
$webapp->header_type('none');
This method used to declare that you are setting a redirection header, or that you want no header to be returned by the framework.
Example of redirecting:
sub some_redirect_mode {
my $self = shift;
# do stuff here....
$self->header_type('redirect');
$self->header_props(-url=> "http://site/path/doc.html" );
}
To simplify that further, use CGI::Application::Plugin::Redirect:
return $self->redirect('http://www.example.com/');
mode_param()# Name the CGI form parameter that contains the run mode name.
# This is the default behavior, and is often sufficient.
$webapp->mode_param('rm');
# Set the run mode name directly from a code ref
$webapp->mode_param(\&some_method);
# Alternate interface, which allows you to set the run
# mode name directly from $ENV{PATH_INFO}.
$webapp->mode_param(
path_info=> 1,
param =>'rm'
);
This accessor/mutator method is generally called in the setup() method. It is used to help determine the run mode to call. There are three options for calling it.
Option 1: A CGI form parameter is named that will contain the name of the run mode to use. This is the default behavior, with 'rm' being the parameter named used.
Option 2: A code reference is provided. It will return the name of the run mode to use directly.
sub some_method {
my $self = shift;
return 'run_mode_x';
}
Option 3: This syntax allows you to easily set the run mode from $ENV{PATH_INFO}. It will try to set the run mode from the first part of $ENV{PATH_INFO} (before the first "/"). To specify that you would rather get the run mode name from the 2nd part of $ENV{PATH_INFO}:
$webapp->mode_param( path_info=> 2 );
You can also set "path_info" to a negative value. If no run mode is found in $ENV{PATH_INFO}, it will fall back to looking in the value of a the CGI form field defined with 'param'.
Using $ENV{PATH_INFO} to name your run mode creates a clean separation between the form variables you submit and how you determine the processing run mode. It also creates URLs that are more search engine friendly.
<form action="/cgi-bin/instance.cgi/edit_form" method=post>
<input type="hidden" name="breed_id" value="4">
/cgi-bin/instance.cgi/edit_form?breed_id=2
prerun_mode()$webapp->prerun_mode('new_run_mode');
The prerun_mode() method is an accessor/mutator which can be used within your cgiapp_prerun() method to change the run mode which is about to be executed.
# In WebApp.pm:
package WebApp;
use base 'CGI::Application';
sub cgiapp_prerun {
my $self = shift;
# Get the web user name, if any
my $q = $self->query();
my $user = $q->remote_user();
# Redirect to login, if necessary
unless ($user) {
$self->prerun_mode('login');
}
}
Note: The prerun_mode() method may ONLY be called in the context of a cgiapp_prerun() method.
Modern web frameworks dispense with cruft in URIs, providing clean URIs instead. Instead of:
/cgi-bin/item.cgi?rm=view&id=15
A clean URI to describe the same resource might be:
/item/15/view
The process of mapping these URIs to run modes is called dispatching and is handled by CGI::Application::Dispatch. Dispatching is not required and is a layer you can fairly easily add to an application later.
You can work on your CGI::Application project on your desktop or laptop without installing a full-featured web-server like Apache. Instead, install CGI::Application::Server from CPAN. After a few minutes of setup, you'll have your own private application server up and running.
Test::WWW::Mechanize::CGIApp allows functional testing of a CGI::App-based project without starting a web server. Test::WWW::Mechanize could be used to test the app through a real web server.
Direct testing is also easy. CGI::Application will normally print the output of its run modes directly to STDOUT. This can be suppressed with an environment variable, CGI_APP_RETURN_ONLY. For example:
$ENV{CGI_APP_RETURN_ONLY} = 1;
$output = $webapp->run();
like($output, qr/good/, "output is good");
CGI::Application has a plug-in architecture that is easy to use and easy to develop new plug-ins for.
For a current complete list, please consult CPAN: http://search.cpan.org/search?m=dist&q=CGI%2DApplication%2DPlugin
Writing plug-ins is simple. Simply create a new package, and export the methods that you want to become part of a CGI::Application project. See CGI::Application::Plugin::ValidateRM for an example.
In order to avoid namespace conflicts within a CGI::Application object, plugin developers are recommended to use a unique prefix, such as the name of plugin package, when storing information. For instance:
$app->{__PARAM} = 'foo'; # BAD! Could conflict.
$app->{'MyPlugin::Module::__PARAM'} = 'foo'; # Good.
$app->{'MyPlugin::Module'}{__PARAM} = 'foo'; # Good.
When writing a plug-in, you may want some action to happen automatically at a particular stage, such as setting up a database connection or initializing a session. By using these 'callback' methods, you can register a subroutine to run at a particular phase.
# register a callback to the standard CGI::Application hooks
# one of 'init', 'prerun', 'postrun', 'teardown' or 'load_tmpl'
# Class-based: callback will persist for all runs of the application
$class->add_callback('init', \&some_other_method);
# Object-based: callback will only last for lifetime of this object
$self->add_callback('prerun', \&some_method);
# If you want to create a new hook location in your application,
# You'll need to know about the following two methods to create
# the hook and call it.
# Create a new hook
$self->new_hook('pretemplate');
# Then later execute all the callbacks registered at this hook
$self->call_hook('pretemplate');
add_callback()$self->add_callback ('teardown', \&callback);
$class->add_callback('teardown', 'method');
The add_callback method allows you to register a callback function that is to be called at the given stage of execution. Valid hooks include 'init', 'prerun', 'postrun' and 'teardown', 'load_tmpl', and any other hooks defined using the new_hook method.
Callbacks can either be object-based or class-based, depending upon whether you call add_callback as an object method or a class method:
# add object-based callback
$self->add_callback('teardown', \&callback);
# add class-based callbacks
$class->add_callback('teardown', \&callback);
My::Project->add_callback('teardown', \&callback);
Object-based callbacks are stored in your web application's $c object; at the end of the request when the $c object goes out of scope, the callbacks are gone too. Class-based callbacks survive for the duration of the running Perl process.
A good place to register class-based callbacks is in your plugin's import subroutine:
package CGI::Application::Plugin::MyPlugin;
use base 'Exporter';
sub import {
my $caller = scalar(caller);
$caller->add_callback('init', 'my_setup');
goto &Exporter::import;
}
new_hook(HOOK)$self->new_hook('pretemplate');
The new_hook() method can be used to create a new location for developers to register callbacks. It takes one argument, a hook name. The hook location is created if it does not already exist. A true value is always returned.
call_hook(HOOK)$self->call_hook('pretemplate', @args);
The call_hook method is used to execute the callbacks that have been registered at the given hook. The first argument to call_hook is the hook name. Any remaining arguments are passed to every callback executed at the hook location.
sub my_hook {
my ($c,@args) = @_;
# ....
}
Object-based callbacks are run before class-based callbacks. The order of class-based callbacks is determined by the inheritance tree of the running application. The built-in methods of cgiapp_init, cgiapp_prerun, cgiapp_postrun, and teardown are also executed this way.
When call_hook('init') is run on a "My::App" application, callbacks installed by these modules are run in order of the @ISA list. If a single class installs more than one callback at the same hook, then these callbacks are run in the order they were registered (FIFO).
Jesse Erlbaum <jesse AT erlbaum.net>
Mark Stosberg has served as a co-maintainer since version 3.2, Martin McGrath became a co-maintainer as of version 4.51, with the help of the numerous contributors documented in the Changes file.
CGI::Application was originally developed by The Erlbaum Group, a software engineering and consulting firm in New York City.
Thanks to Vanguard Media (http://www.vm.com) for funding the initial development of this library and for encouraging Jesse Erlbaum to release it to the world.
Many thanks to Sam Tregar (author of the most excellent HTML::Template module!) for his innumerable contributions to this module over the years, and most of all for getting me off my ass to finally get this thing up on CPAN!
Many other people have contributed specific suggestions or patches, which are documented in the "Changes" file.
Thanks also to all the members of the CGI-App mailing list! Your ideas, suggestions, insights (and criticism!) have helped shape this module immeasurably. (To join the mailing list, visit http://lists.openlib.org/mailman/listinfo/cgiapp)
CGI::Application : Framework for building reusable web-applications Copyright (C) 2000-2003 Jesse Erlbaum <jesse AT erlbaum.net>
This module is free software; you can redistribute it and/or modify it under the terms of either:
This program 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 either the GNU General Public License or the Artistic License for more details.
You should have received a copy of the Artistic License with this module, in the file ARTISTIC. If not, I'll be glad to provide one.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Generated by phpman v4.9.26-5-g7740029 Author: Che Dong Under GNU General Public License
2026-08-23 20:35 @216.73.216.102
CrawledBy Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)