Help-Site Computer Manuals
  Algorithms & Data Structures   Programming Languages   Revision Control
  Cameras   Computers   Displays   Keyboards & Mice   Motherboards   Networking   Printers & Scanners   Storage
  Windows   Linux & Unix   Mac

Map URIs to perl package namespaces

ModPerl::PackageRegistry - Map URIs to perl package namespaces


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



 package MyWebsite::pages::index;

 use strict;

 use warnings;


 use Apache2::RequestRec ();

 use Apache2::Const q(OK);


 return 1;


 sub page {

     my($class, $r) = @_;


     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:

  • The 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.

  • Any file extensions are removed.
  • 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

    Then, if somebody requested /some/, ModPerl::PackageRegistry would look for a handler in MyPackage::foo::some::stuff.

  • Slashes are converted to double-colons (::)
  • 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, C<ModPerl::PackageRegistry> is done it's work and the

rest is up to you!


The Directory Must Exist

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 /, whether or not actually exists.

However, if you request /, and that is resolved to / by a DirectoryIndex directive, 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.


Tyler ``Crackerjack'' MacDonald <>.

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.