The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CGI::Application::Dispatch - Class used to dispatch request to CGI::Application based objects

SYNOPSIS

Under mod_perl

    <Location /app>
        SetHandler perl-script
        PerlHandler CGI::Application::Dispatch
    </Location>

Under normal cgi

    #!/usr/bin/perl
    use strict;
    use CGI::Application::Dispatch;

    CGI::Application::Dispatch->dispatch();

DESCRIPTION

This module provides a way (as a mod_perl handler or running under vanilla CGI) to look at the path ($r->path_info or $ENV{PATH_INFO}) of the incoming request, parse off the desired module and it's run mode, create an instance of that module and run it.

It will translate a URI like this (under mod_perl):

        /app/module_name/run_mode?extra_stuff...

or this (vanilla cgi)

        /app/index.cgi?/module_name/run_mode?extra_stuff...

into something that will be functionally similar to this

        my $app = Module::Name->new(..);
        $app->mode_param(sub {'run_mode'}); #this will set the run mode

MOTIVATION

To be honest I got tired of writing lots of individual instance scripts, one for each application module, under the traditional style of CGI::Application programming. Then when I switched to running my CGI::Application modules as straight mod_perl handlers I got tired of having to change my httpd.conf file for every module I introduced and having my configuration file full of Location sections. Since I had moved all of my configuration variables into config files and was not passing any values into the PARAMS hash upon module creation I decided not to write the same code over and over.

I guess it comes down to me just being lazy. :)

OPTIONS

This section describes the different options that are available to customize how you dispatch your requests. All of these options can either be set using 'PerlSetVar' (if you're running under mod_perl) or passed directly as name-value pairs to the dispatch() method. We we have examples so don't worry too much.

CGIAPP_DISPATCH_PREFIX

This option will set the string that will be prepended to the name of the application module before it is loaded and created. So to use our previous example request of

    /app/index.cgi?/module_name/run_mode?extra_stuff

This would be default load and create a module named Module::Name. But let's say that you have all of your application specific modules under the 'My' namespace. If you set

CGIAPP_DISPATCH_NO_RM

This option, if true, will tell C::A::Dispatch to not set the run mode for the application,

METHODS

handler()

This method is used so that this module can be run as a mod_perl handler. When it creates the application module it passes the $r argument into the PARAMS hash of new()

    <Location /app>
        SetHandler perl-script
        PerlHandler CGI::Application::Dispatch
        PerlSetVar  CGIAPP_DISPATCH_PREFIX MyApp
        PerlSetVar  CGIAPP_DISPATCH_RM Off 
    </Location>

The above example would tell apache that any url beginning with /app will be handled by CGI::Application::Dispatch. It also sets the prefix used to create the application module to 'MyApp' and it tells CGI::Application::Dispatch that it shouldn't set the run mode but that it will be determined by the application module as usual (through the query string).

dispatch()

This method is primarily used in a non mod_perl setting in an small cgi script to dispatch requests. You can pass this method the same name value pairs that you would set for the handler() method using the same options mentioned above.

    #!/usr/bin/perl
    use strict;
    use CGI::Application::Dispatch;

    CGI::Application::Dispatch->dispatch(
            CGIAPP_DISPATCH_PREFIX => 'MyApp',
            CGIAPP_DISPATCH_RM => 0,
        );

This example would do the same thing that the previous example of how to use the handler() method would do. The only difference is that it is done in a script and not in the apache configuration file.

The benefit to using CGI::Application::Dispatch in a non mod_perl environment instead of the traditional instance scripts would only be seen in an application that has many instance scripts. It would mean your application would only need one script and many application modules. Since the dispatch script is so simple you just write it once and forget about it and turn your attention to your modules and templates.

get_module_name($path_info, $prefix)

This method is used to control how the module name is generated from the PATH_INFO. Please see "PATH_INFO Parsing" for more details on how this method performs it's job. The main reason that this method exists is so that it is overridden if it doesn't do exactly what you want.

You shouldn't actually call this method yourself, just override it if necessary.

get_runmode($path_info)

This method is used to control how the run mode is generated from the PATH_INFO. Please see "PATH_INFO Parsing" for more details on how this method performs it's job. The main reason that this method exists is so that it is overridden if it doesn't do exactly what you want.

You shouldn't actually call this method yourself, just override it if necessary.

PATH_INFO Parsing

This section will describe how the application module and run mode are determined from the PATH_INFO and what options you have to customize the process.

Getting the module name

To put it simply, the PATH_INFO is split on backslahes (/). The second element of the returned list is used to create the application module. So if we have a path info of

    /module_name/mode1

Then the string 'module_name' is used. Underscores (_) are turned into double colons (::) and each word is passed through ucfirst so that the first letter of each word is captialized.

Then the CGIAPP_DISPATCH_PREFIX is added to the beginning of this new module name with a double colon :: separating the two.

If you don't like the exact way that this is done, don't fret you do have an option. Just override the get_module_name() method by writing your own dispatch class that inherits from CGI::Application::Dispatch.

Getting the run mode

Just like the module name is retrieved from splitting the PATH_INFO on backslashes, so is the run mode. Only instead of using the second element of the resulting list, we use the third as the run mode. So, using the same example, if we have a path info of

    /module_name/mode1

Then the string 'mode1' is used as the run mode unless the CGIAPP_DISPATCH_RM is set to false. As with the module name this behavior can be changed by overriding the get_runmode() sub.

AUTHOR

Michael Peters <michael@petersfamily.org>

COMMUNITY

This module is a part of the larger CGI::Application community. If you have questions or comments about this module then please join us on the cgiapp mailing list by sending a blank message to "cgiapp-subscribe@lists.erlbaum.net". There is also a community wiki located at http://twiki.med.yale.edu/twiki2/bin/view/CGIapp/WebHome.

SEE ALSO

CGI::Application, Apache::Dispatch

TODO

  • Create a more complete test suite.

  • add easier alias for options for dispatch()