| ModPerl-PackageRegistry documentation | view source | Contained in the ModPerl-PackageRegistry distribution. |
ModPerl::PackageRegistry - Map URIs to perl package namespaces
<Location /dynamic> SetHandler perl-script PerlResponseHandler ModPerl::PackageRegistry PackageNamespace MyWebsite::pages PackageBase /dynamic PackageIndex index PackageHandler ->page </Location>
package MyWebsite::pages::index;
use strict;
use warnings;
use Apache2::RequestRec ();
use Apache2::Const q(OK);
return 1;
sub page {
my($class, $r) = @_;
$r->do_stuff();
return OK;
}
This mod_perl2 handler allows you to directly map a path in your apache 2.x
server to a package namespace in perl. When the handler is invoked, it
transforms the URI requested into the name of a perl module, and if that
module is found, executes the handler specified by the PackageHandler
directive.
The transformation is done as follows:
PackageBase directive is applied.If a URI is specified in the PackageBase directive, that is stripped from
the beginning of the URI in the request. (eg; if the browser requests
/foo/bar/baz, and PackageBase is /foo/bar, we are going to be
searching for /baz.)
PackageBase defaults to "/".
Note that ModPerl::PackageRegistry will decline to act as a handler
if PackageBase is defined, and the URL the browser requested doesn't
match it.
The dot (.) is not a good character for a perl module's name, so anything found after it is removed. This allows you to do stuff like:
<Files "*.pr"> SetHandler perl-script PerlResponseHandler ModPerl::PackageRegistry PackageNamespace MyPackage::foo </Files>
Then, if somebody requested /some/stuff.pr, ModPerl::PackageRegistry
would look for a handler in MyPackage::foo::some::stuff.
This is pretty self-explanitory; the web's namespace separator is /,
whereas perl's is ::.
PackageNamespace is prepended to the package's name.Again, pretty self-explanitory; if PackageNamespace is foo and
we're looking for bar::baz, the actual package we're going to try
to load is foo::bar::baz.
PackageIndex is applied if the request is for a directory.The PackageIndex parameter allows you to specify what to append to
the package name if a directory was requested. For example, if somebody
requested /somewhere/else and PackageIndex was set to hello,
we would be looking for MyPackage::foo::somehwere::else::hello.
We then attempt to load the module. If loading the module is successful,
then we try to invoke it's handler. The handler is specified by the
PackageHandler directive. (By default, it is set to the mod_perl
default, handler). If you would like your handler to be invoked as
a method rather than a function, then place a "->" in front of the method's
name, like so:
PackageHandler ->method
At that point, ModPerl::PackageRegistry is done it's work and the
rest is up to you!
Apache needs to be able to at least find a directory to serve from, even if the content it's serving is from a perl namespace. One way around this is to make your DocumentRoot the start of your perl namespace, eg:
DocumentRoot /usr/local/lib/perl/5.8.4/MyWebsite/pages
PackageIndex will only work correctly if ModPerl::PackageRegistry is
the handler for your entire directory tree. This is because of the
way Apache interprets the DirectoryIndex directive.
If you have a handler for ".pl" files, that handler will be invoked when you request /foo.pl, whether or not foo.pl actually exists.
However, if you request /, and that is resolved to /index.pl by a
DirectoryIndex directive, index.pl must exist or else apache2
will return a NOT_FOUND response without ever invoking your handler.
If you wish to mix static and dynamic content in the same directory tree, there are three ways (that I know of) to get around this problem.
If you have an empty file called index.whatever in each of your directories,
that will cause your handler to be invoked as usual.
Also solves the "Directory Must Exist" problem above, but this means that you have to scatter your static content around with your perl modules. (Is that actually such a bad thing?)
Like so:
<LocationMatch "/$"> SetHandler perl-script PerlResponseHandler ModPerl::PackageRegistry PackageIndex index PackageNamespace MyWebsite::pages </LocationMatch>
Tyler "Crackerjack" MacDonald <japh@crackerjack.net>.
The "TestCommon::LogDiff" package, used by the test suite, was pilfered from the mod_perl 2.0.2 distribution.
This is free software; you may redistribute it under the same terms as perl itself.
| ModPerl-PackageRegistry documentation | view source | Contained in the ModPerl-PackageRegistry distribution. |