Background:
I'm working on a site that is a mix of php (which I'm gradually converting to
mod_perl) and mod_perl (running under Apache::Registry and using Template Toolkit
(TT2)) using an apache configuration like this:
<Directory />
[...]
<Files "*.par">
SetHandler perl-script
PerlHandler Apache::Registry
Options ExecCGI
PerlSendHeader On
</Files>
</Directory>
I took the <Files> approach because, at the time, it seemed like the easiest way to
have *.php and *.par files coexist during the conversion.
Problem:
There are many *.par pages (estimate: 70-100 when conversion is complete), and they
all contain the following code with minor variations that could be made consistent
(like what constants are imported, what modules are "use"d, etc.). I'd like to find a
way to prevent having that code (below) show up over and over again so I can eliminate
a potential maintenance headache, but I'm not sure of what's a good way to bundle it
up for reuse.
One idea I had was to write a handler that acts as a sort of minimal application
framework that contains the code below and determines what perl module should be
"require"d and executed based on $apache->path_info and $apache->uri. This sounds
like a substantial effort, but would provide a centralized framework where I could add
features that apply to all pages by only editing code in one place. Is this a
reasonable approach? Are there other simpler approaches?
I'd appreciate any input on how other people are structuring similar type applications
in mod_perl, where the output is generated by Template Toolkit based on data obtained
via SQL queries using parameters received mostly in the URL.
#--- BEGIN SAMPLE PAGE testpage.par ---
#!/usr/local/bin/perl -wT
#------------------------------------------------------------
BEGIN {
require "$MyCompany::Basepath->{sitename}/MyCompany/ProjectName/Config/Startup.pl";
}
use Apache ();
use Apache::Constants qw(:common SERVER_ERROR REDIRECT);
use Apache::DBI;
use strict;
our $apache = Apache->request;
### I realize that I should be handling header_only requests a little differently, but
code not updated yet.
$apache->content_type('text/html');
if ($apache->header_only) {
$apache->send_http_header;
return OK;
};
my $parm = {$apache->args, $apache->content};
my $dbi = $MyCompany::ProjectName::Config::dbi;
my $dbh = DBI->connect($dbi->{dsn}, $dbi->{user}, $dbi->{password},
{RaiseError => 1});
# template object is built in apache startup.perl file (before fork)
my $out = &dispatch($apache, $parm, $dbh, $MyCompany::ProjectName::template);
$apache->send_http_header;
print $out;
return OK;
sub dispatch {
my ($apache, $parm, $dbh, $tpl) = @_;
my $template_data;
### [... fill $template_data with something meaningful here ...] ###
my $output = "";
$tpl->process('viewsurveyusers.tpl', $template_data, \$output)
or die "Error processing template: ".$tpl->error;
return $output;
}
#--- END SAMPLE PAGE testpage.par ---
Relevant piece of startup.perl:
#---- BEGIN ---
use Template;
$MyCompany::ProjectName::template = Template->new(INCLUDE_PATH => "tt",
PRE_PROCESS => "config.tpl",
PRE_CHOMP => 1,
);
#--- END ---
Matthew Pressly