Apache::Request::Dispatcher - dispatches requests to a sub-class of Apache::Request::Controller
<Location /myApplication> SetHandler perl-script Perlhander Apache::Request::Dispatcher SetEnv DispatcherConf /path/to/file.cfg setEnv APP_NAME myApplication </Location>
Apache::Request::Dispatcher is a mod_perl handler which handles Apache HTTP requests under mod_perl, and dispatches them to a sub-class of Apache::Request::Controller (after some initial request setup has been performed).
If required, it will establish a connection to a database using the DBI, retrieve (or create) session data for this request (using Apache::Session), initialise a template processor (using the Template-Toolkit).
The Dispatcher parses the URI of the request to determine which subclass of Apache::Request::Controller to then pass control to.
Parsing of the URI occurs as follows:
APP_NAME (environment set in Apache Config) is removed from the begining of the URI, so that:
'/myApplication/SubClass/action'
becomes: 'SubClass/action'
or
'/myApplication/Sub/Class/action'
becomes: 'Sub/Class/action'
This is then converted to a module name, and a method name, such as:
Apache::Request::Controller::SubClass or Apache::Request::Controller::Sub::Class
with action() being the method name.
It should be noted that if the SubClass or Action name contain any thing other than [A-Za-z0-9_] then the request is declined.
The dispatcher then dynamically inherits from the module name, and then calls $self->action().
The action() method of the controller is then called in an object-oriented fashion, with a dispatcher object passed in as its first parameter.
This object contains the following hash elements:
request => $r, # The Apache Request Object dbh => $dbh, # The Database Connection Object cfg => $cfg, # The AppConfig object template => $template, # The Template Processor apr => $q, # The CGI/libapreq object session => \%session # Any session data for this user
Depending on the configuration file, 'dbh' or 'session' may be undefined if they've been turned off.
an example controller method might be written as follows:
package Apache::Request::Controller::SubClass; our @ISA = qw(Apache::Request::Controller); use strict; use Apache::Const qw(:common :methods :http); sub action { my $self = shift; my $thing = getThingByID($self->{'dbh'}, $self->{'apr'}->param('thingId')); $self->{'request'}->status(HTTP_OK); $self->{'request'}->content_type('text/html'); $self->{'template'}->process('myTemplate', {thing => $thing}); return OK; } 1;
Generally, the controllers that are dispatched to will generate dynamic content, and as such the dispatcher automatically sets the browsers caching policy to not cache any content. However, if your Controller sub-class has a method called __cache() then will be used to define the caching policy. The action name is given as a parameter to the __cache() method, and based on this, the __cache() method should return 1 to allow caching, or zero to prevent it.
For exmaple, if your Controller sub-class provides 2 actions, staticContent() and dynamicContent(), then your __cache() method can control the caching policy as follows:
sub __cache { my $action = shift; my $policy = { staticContent => 1, dynamicContent => 0}; return $policy->{$action} || 0; # Default to no caching. }
If your Controller sub-class wants to turn off caching globally, then you can just return zero regardless of what the action name is.
If the dispatcher cannot work out which action the request is for (this happens on a URI such as '/myApplication/SubClass') then the dispatcher checkes to see if the Controller SubClass has a 'default' action by calling __index(). If this method does not exist, then the request is declined. The __index() method should return the name of the default action, such as:
sub __index { return 'listAllItems'; }
The template processor has the following defaults defined, and may be used by all templates:
This template variable is a reference to a subroutine which will add comma's in the right place in numbers, for exmaple:
[% DisplayNumber(1000) %] becomes 1,000
This template variable is a reference to a subroutine which will take a time value (in the form of seconds since the epoch) and display the actual date. You may optionally specify an strftime() format:
[% DisplayDate( CURRENT_TIME, '%a %d %B %Y' ) %]
This template variable is a reference to a subroutine which will take a time value (in the form of seconds since the epoch) and displays the time-of-day. You may optionally specify an strftime() format:
[% DisplayTime( CURRENT_TIME, '%a %d %B %Y' ) %]
This template variable is a reference to a subroutine which will take a time value (in the form of seconds since the epoch) and displays the date and time of day
[% DisplayDateTime( CURRENT_TIME ) %]
This template variable is a reference to a subroutine which will take a number of seconds as input, and output a string of the form 'H hours, M minutes and S seconds', eg:
Last Modified: [% DisplayDuration( CURRENT_TIME - LAST_MODIFIED %]
This template variable is a string which represents the application name, as defined by the environment variable APP_NAME.
This template variable is an Apache2::RequestRec object, so that the template can have access to the current URI etc. Its not really meant to be used to set any outgoing headers or any thing tho, as setting up the response should really be done in the Controller.
The dispatcher can be used to dispatch to multiple controllers that dont even need to belong to the same application, and each can application can have its own database connection and set of templates. This is achieved by having Apache specify which configuration file to use based on the Location of the request URI. For example:
will specify that all requests with a root-URI of /myApplication will use the configuration file as specified in the DispatcherConf environment variable, which is /path/to/file.cfg in the above example.
The contents of this configuration file are as follows:
db_dsn="DBI:Pg:database=myApplication;host=127.0.0.1" db_username=apache db_password=apache templatePath="/data/myApplication/templates" defaultController=WelcomePage # If you wish to use sessions, uncomment this and make sure you have # created the sessions table within the database db_dsn. useSessions="Apache::Session::Postgres" sessionTable="sessions"
where db_dsn, db_username, and db_password specifies the database connection options, templatePath specifies where the templates are all stored, and defaultController specifies which controller is the default, so that if a request for '/myApplication' is recieved, it will be converted to '/myApplication/WelcomePage', which will in turn get converted to Apache::Request::Controller::WelcomePage.
At a minimum, you have to have templatePath defined. If you dont specify a default Controller, then the top-level URI will not work.
Bradley Kite <bradley-cpan@kitefamily.co.uk>
If you wish to email me, then please remove the '-cpan' part of my email address as anything addressed to 'bradley-cpan' is assumed to be spam and is not read.
Apache::Request::Controller, DB::Table, DB::Table::Row, DBI, perl
1 POD Error
The following errors were encountered while parsing the POD:
=pod directives shouldn't be over one line long! Ignoring all 2 lines of content
To install Apache::Request::Controller, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Apache::Request::Controller
CPAN shell
perl -MCPAN -e shell install Apache::Request::Controller
For more information on module installation, please visit the detailed CPAN module installation guide.