CGI::SHTML - a CGI module for parsing SSI


  use CGI::SHTML;
  my $cgi = new CGI::SHTML;
  # Print a full page worth of info
  print $cgi->header();
  print $cgi->start_html('internal', -title=>"SAMPLE PAGE");
  # Insert content here
  print $cgi->end_html('internal', -author=>"Webmaster", 
  # Just parse some SSI text
  my @text = '<!--#echo var="TITLE"-->';
  print CGI::SHTML->parse_shtml(@text);
  # Use a different configuration file
  BEGIN { $CGI::SHTML::CONFIG = "/home/tskirvin/"; }
  use CGI::SHTML;

Further functionality is documented with the CGI module.


In order to parse SSI, you generally have to configure your scripts to be re-parsed through Apache itself. This module eliminates that need by parsing SSI headers itself, as best it can.

Some information on SSI is available at


Defines a file that has further configuration for your web site. This is useful to allow the module to be installed system-wide without actually requiring changes to be internal to the file. Note that you'll need to reset this value *before* loading CGI::SHTML if you want it to actually make any difference; it's loaded when you load the module.


new ()
Invokes CGI's new() command, but blesses with the local class. Also performs the various local functions that are necessary.

parse_shtml ( LINE [, LINE [, LINE ]] )
Parses LINE as if it were an SHTML file. Returns the parsed set of lines, either in an array context or as a single string suitable for printing. All of the work is actually done by ssi().

Does the work of parsing an SSI statement. COMMAND is one of the standard SSI ``tags'' - 'echo', 'include', 'fsize', 'flastmod', 'exec', 'set', 'config', 'odbc', 'email', 'if', 'goto', 'label', and 'break'. ARGS is a string containing the rest of the SSI command - it is parsed by this function.

Note: not all commands are implemented. In fact, all that is implemented is 'echo', 'include', 'fsize', 'flastmod', 'exec', 'if/elif/else/endif', and 'set'. These are all the ones that I've actually had to use to this point.

start_html ( TYPE, OPTIONS )
Invokes CGI::start_html, and includes the appropriate header file. OPTIONS is passed directly into CGI::start_html, after being parsed for the 'title' field (which is specially set). TYPE is used to decide which header file is being used; the possibilities are in $CGI::SHTML::HEADER.

end_html ( TYPE, OPTIONS )
Loads the appropriate footer file out of $CGI::SHTML::FOOTER, and invokes CGI::end_html.


This module was generated for a single research group at UIUC. Its goal was simple: parse the SSI header and footers that were being used for the rest of the web site, so that they wouldn't have to be re-implemented later. Ideally, we would liked to just have Apache take care of this, but it wasn't an option at the time (and as far as I know it still isn't one.)

I mention the above because it's worth understanding the problem before you think about its limitations. This script will not offer particularly high performance for reasonably-sized sites that use a lot of CGI; I doubt it would work at all well with mod_perl, for instance. But it has done the job just fine for our research group, however; and if you want to copy our general website layout, you're going to need something like this to help you out.

Also of note is that this has been designed for use so that if headers and footers are not being included, you can generally fall back to the default fairly easily enough.

Also of note are the security issues. There are lots of ways for the user to run arbitrary code with this module; however, there were already plenty of ways for them to do it if you're giving them unfettered SSI access. This isn't a change. So make sure that the user that your webserver runs as isn't a particularly priveleged user, and *never* run code through this that came from the outside! You would be a fool to do otherwise.



There are still a few functions that should be better implemented (format strings for flastmod(), for instance). It might be nice to make this more object-oriented as well; as it stands this wouldn't stand a chance with mod_perl.


Tim Skirvin <>



This code is distributed under the University of Illinois Open Source License. See for details.


Copyright 2000-2004 by the University of Illinois Board of Trustees and Tim Skirvin <>.