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/ .

  • echo

  • exec

  • fsize

  • flastmod

  • include

  • printenv

  • set

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

  • config

    Not supported yet.

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
 PerlHandler My::BeforeSSI Apache::SSI My::AfterSSI
</Files>

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

The date output formats are different from mod_include's format. Anyone know a nice way to get the same format without resorting to HTTP::Date? [update: Byron Brummer suggests that I check out the POSIX::strftime() function, included in the standard distribution.]

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

#if .. #else should be possible now, I'll take a stab it implementing it.

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.

BUGS

The only xssi directives currently supported are 'set' and 'echo'.

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.