greetings...
I have proposed the following to the mod_perl list and sent an RFC - no
comments, good or bad...
just making sure everyone on this alias thinks the new module appropriate
and well formed before it goes into CPAN...
below is the module in its entirety (it's short) - please let me know if
this is appropriate for future work...
thanks
--Geoff
package Apache::Wrapper;
#---------------------------------------------------------------------------
----
#
# usage: PerlHandler Apache::Wrapper
# PerlSetVar TEMPLATE "/path/to/template.html" # relative to server
root
# PerlSetVar REPLACE "|" # character or string
# defaults to "|"
# PerlSetVar Filter On # optional - will
work
# within
Apache::Filter
#---------------------------------------------------------------------------
----
use 5.004;
use mod_perl 1.21;
use Apache::Constants qw( OK DECLINED SERVER_ERROR );
use Apache::File;
use Apache::Log;
use strict;
$Apache::Wrapper::VERSION = '0.01';
sub handler {
#---------------------------------------------------------------------------
----
# initialize request object and variables
#---------------------------------------------------------------------------
----
my $r = shift;
my $log = $r->server->log;
my $template = $r->server_root_relative .
$r->dir_config('TEMPLATE');
my $DEBUG = 1; # 0 - messages at info or debug log levels
# 1 - verbose output at info or debug log
levels
my $replace = $r->dir_config('REPLACE') || "|";
# make Apache::Filter aware using the 'Filter' perl variable in httpd.conf
my $filter = 1 ? $r->dir_config('Filter') =~ m/On/i : 0;
#---------------------------------------------------------------------------
----
# do some preliminary stuff...
#---------------------------------------------------------------------------
----
$log->info("Using Apache::Wrapper");
unless ($r->content_type eq 'text/html') {
$log->info("\trequest is not for an html document - skipping...") if
$DEBUG;
$log->info("Exiting Apache::Wrapper");
return DECLINED;
}
#---------------------------------------------------------------------------
----
# wrap the template around the requested file...
#---------------------------------------------------------------------------
----
$log->info("\tlooking for \'$replace\' in template $template") if $DEBUG;
# open the template handle
my $tph = Apache::File->new($template);
unless ($tph) {
$log->error("\tcannot open template! $!");
$log->info("Exiting Apache::Wrapper");
return SERVER_ERROR;
}
# open the request handle
my $rqh;
if ($filter) {
$log->info("\tgetting input from Apache::File") if $DEBUG;
$rqh = $r->filter_input;
} else {
$log->info("\tgetting input from requested uri") if $DEBUG;
$rqh = Apache::File->new($r->filename);
}
unless ($rqh) {
$log->warn("\tcannot open request! $!");
$log->info("Exiting Apache::Wrapper");
return DECLINED;
}
# output
while (<$tph>) {
if (/\Q$replace/) {
$log->info("\t\'$replace\' found - replacing with request") if $DEBUG;
my ($left, $right) = split /\Q$replace/;
# calling $r->print circumvents Apache::Filter, so just use print
print $left; # output the left side of substitution
if ($filter) {
while(<$rqh>) {
print $_; # output the requested file line by line
}
} else { # if not using Apache::Filter, just dump
$r->send_fd($rqh); # the file for performance improvement
}
print $right; # ouptut the right side of substitution
}
else {
print $_; # print each template line
}
}
#---------------------------------------------------------------------------
----
# wrap up...
#---------------------------------------------------------------------------
----
$log->info("Exiting Apache::Wrapper");
return OK;
}
1;
__END__
=head1 NAME
Apache::Wrapper - a simple framework for creating uniform, template driven
content.
=head1 SYNOPSIS
httpd.conf:
<Location /someplace>
SetHandler perl-script
PerlHandler Apache::Wrapper
PerlSetVar TEMPLATE "templates/format1.html"
PerlSetVar REPLACE "the content goes here"
</Location>
Apache::Wrapper is Filter aware, meaning that it can be used within
an Apache::Filter framework without modification. Just include the
directive
PerlSetVar Filter On
and modify the PerlHandler directive accordingly...
=head1 DESCRIPTION
Apache::Wrapper provides a simple way to insert content within an
established
template for uniform content delivery. While the end result is similar to
Apache::Sandwich, Apache::Wrapper offers several advantages.
It does not use separate header and footer files, easing the pain of
maintaining
syntactically correct HTML in seperate files.
It is Apache::Filter aware, thus it can both accept content from other
content handlers as well as pass its changes on to others later in the
chain.
=head1 EXAMPLE
/usr/local/apache/templates/format1.html:
<html>
<head><title>your template</title></head>
<title>your template</title>
<body bgcolor="#778899">
some headers, banners, whatever..
<p>
the content goes here
</p>
<p>some footers, modification dates, whatever...
</body>
</html>
httpd.conf:
PerlModule Apache::Filter
<Location /someplace>
SetHandler perl-script
PerlHandler Apache::Wrapper Custom::SomeOtherHandler
PerlSetVar TEMPLATE "templates/format1.html"
PerlSetVar REPLACE "the content goes here"
PerlSetVar Filter On
</Location>
Now, a request to http://localhost/someplace/foo.html will insert the
contents of
foo.html in place of "the content goes here" in the format1.html template
and pass
those results to Custom::SomeOtherHandler. The result is a nice and tidy
way to
control any custom headers, footers, background colors or images, in a
single html
file.
=head1 NOTES
TEMPLATE is relative to the ServerRoot - this may change in future
releases, depending
on demand.
REPLACE defaults to "|", though it may be any character or string you
like - metacharacters are disabled in the search, so sorry, no regex for
now...
Verbose debugging is enabled by setting $Apache::Wrapper::DEBUG=1 or
greater.
To turn off all debug information, set your apache LogLevel above info
level.
This is alpha software, and as such has not been tested on multiple
platforms or
environments. It requires PERL_LOG_API=1, PERL_FILE_API=1, and maybe
other hooks
to function properly.
=head1 FEATURES/BUGS
If Apache::Wrapper finds more than one match for REPLACE in the template,
it
will insert the request for the first occurrence only. All other
replacement
strings will just be stripped from the template.
Currently, Apache::Wrapper will return DECLINED if the content-type of the
request is not 'text/html'.
=head1 SEE ALSO
perl(1), mod_perl(3), Apache(3), Apache::Filter(3)
=head1 AUTHOR
Geoffrey Young <[EMAIL PROTECTED]>
=head1 COPYRIGHT
Copyright 2000 Geoffrey Young - all rights reserved.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut