NAME
Apache::SSI - Implement Server Side Includes in Perl
SYNOPSIS
In httpd.conf:
<Files *.phtml> # or whatever
SetHandler perl-script
PerlHandler Apache::SSI
</Files>
You may wish to subclass Apache::SSI for your own extensions. If so, compile mod_perl with PERL_METHOD_HANDLERS=1 (so you can use object-oriented inheritance), and create a module like this:
package MySSI;
use Apache::SSI ();
@ISA = qw(Apache::SSI);
#embedded syntax:
#<!--#something param=value -->
sub ssi_something {
my($self, $attr) = @_;
my $cmd = $attr->{param};
...
return $a_string;
}
Then in httpd.conf:
<Files *.phtml>
SetHandler perl-script
PerlHandler MySSI
</Files>
DESCRIPTION
Apache::SSI implements the functionality of mod_include for handling server-parsed html documents. It runs under Apache's mod_perl.
In my mind, there are two main reasons you might want to use this module: you can sub-class it to implement your own custom SSI directives, and/or you can parse the output of other mod_perl handlers, or send the SSI output through another handler (use Apache::Filter or Apache::OutputChain to do these).
Each SSI directive is handled by an Apache::SSI method with the prefix "ssi_". For example, <!--#printenv--> is handled by the ssi_printenv method. attribute=value pairs inside the SSI tags are parsed and passed to the method in an anonymous hash.
SSI Directives
This module supports the same directives as mod_include. At least, that's the goal. =) For methods listed below but not documented, please see mod_include's online documentation at http://www.apache.org/ .
config
echo
exec
fsize
flastmod
include
printenv
set
if
elif
else
endif
perl
There are two ways to call a Perl function, and two ways to supply it with arguments. The function can be specified either as an anonymous subroutine reference, or as the name of a function defined elsewhere:
<!--#perl sub="sub { localtime() }"--> <!--#perl sub="time::now"-->
If the 'sub' argument matches the regular expression /^\s*sub[^\w:]/, it is assumed to be a subroutine reference. Otherwise it's assumed to be the name of a function. In the latter case, the string "::" will be prepended to the function name if the name doesn't contain "::" (this forces the function to be in the main package, or a package you specify).
If you want to supply a list of arguments to the function, you use either the "arg" or the "args" parameter:
<!--#perl sub="sub {$_[0] * 7}" arg=7--> <!--#perl sub=holy::matrimony arg=Hi arg=Lois--> <!--#perl sub=holy::matrimony args=Hi,Lois-->
The "args" parameter will simply split on commas, meaning that currently there's no way to embed a comma in arguments passed via the "args" parameter. Use the "arg" parameter for this.
If you give a key-value pair and the key is not 'sub', 'arg', 'args', or 'pass_request' (see below), then your routine will be passed both the key and the value. This lets you pass a hash of key-value pairs to your function:
<!--#perl sub=holy::matrimony groom=Hi bride=Lois--> Will call &holy::matrimony('groom', 'Hi', 'bride', 'Lois');
As of version 1.95, we pass the current Apache request object ($r) as the first argument to the function. To turn off this behavior, give the key-value pair 'pass_request=no', or put 'PerlSetVar SSIPerlPass_Request no' in your server's config file.
See
http://perl.apache.org/src/mod_perl.html
for more information on Perl SSI calls.
CHAINING HANDLERS
There are two fairly simple ways for this module to exist in a stacked handler chain. The first uses Apache::Filter
, and your httpd.conf would look something like this:
PerlModule Apache::Filter
PerlModule Apache::SSI
PerlModule My::BeforeSSI
PerlModule My::AfterSSI
<Files ~ "\.ssi$">
SetHandler perl-script
PerlSetVar Filter On
PerlHandler My::BeforeSSI Apache::SSI My::AfterSSI
</Files>
The "PerlSetVar Filter On"
directive tells the three stacked handlers that they should use their filtering mode. It's mandatory.
The second uses Apache::OutputChain
, and your httpd.conf would look something like this:
PerlModule Apache::OutputChain
PerlModule Apache::SSIChain
PerlModule My::BeforeSSI
PerlModule My::AfterSSI
<Files ~ "\.ssi$">
SetHandler perl-script
PerlHandler Apache::OutputChain My::AfterSSI Apache::SSIChain My::BeforeSSI
</Files>
Note that the order of handlers is reversed in the two different methods. One reason I wrote Apache::Filter
is to get the order to be more intuitive. Another reason is that Apache::SSI
itself can be used in a handler stack using Apache::Filter
, whereas it needs to be wrapped in Apache::SSIChain
to be used with Apache::OutputChain
.
Please see the documentation for Apache::OutputChain
and Apache::Filter
for more specific information.
CAVEATS
Currently, the way <!--#echo var=whatever--> looks for variables is to first try $r->subprocess_env, then try %ENV, then the five extra environment variables mod_include supplies. Is this the correct order?
TO DO
Revisit http://www.apache.org/docs/mod/mod_include.html and see what else there I can implement.
It would be nice to have a "PerlSetVar ASSI_Subrequests 0|1" option that would let you choose between executing a full-blown subrequest when including a file, or just opening it and printing it.
I'd like to know how to use Apache::test for the real.t test.
SEE ALSO
mod_include, mod_perl(3), Apache(3), HTML::Embperl(3), Apache::ePerl(3), Apache::OutputChain(3)
AUTHOR
Ken Williams ken@forum.swarthmore.edu
Concept based on original version by Doug MacEachern dougm@osf.org . Implementation different.
COPYRIGHT
Copyright 1998 Swarthmore College. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.