ssi.html revision 235a3e48d17b30fafb12619ee145300bdb67dd00
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<html>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<head>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<title>Apache Tutorial: Introduction to Server Side Includes</title>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<link rev="made" href="mailto:rbowen@rcbowen.com">
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</head>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<!-- Background white, links blue (unvisited), navy (visited), red (active) -->
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#000080"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncalink="#FF0000">
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<!--#include virtual="header.html" -->
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h1 align="CENTER">Apache Tutorial: Introduction to Server Side
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIncludes</h1>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a name="__index__"></a> <!-- INDEX BEGIN -->
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href=
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync"#apachetutorial:introductiontoserversideincludes">Apache
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTutorial: Introduction to Server Side Includes</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#whataressi">What are SSI?</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#configuringyourservertopermitssi">Configuring your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncserver to permit SSI</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#basicssidirectives">Basic SSI directives</a>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li><a href="#today'sdate">Today's date</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li><a href="#modificationdateofthefile">Modification date of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfile</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <li><a href="#includingtheresultsofacgiprogram">Including the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncresults of a CGI program</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#additionalexamples">Additional examples</a>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#whenwasthisdocumentmodified">When was this document
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmodified?</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#includingastandardfooter">Including a standard
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfooter</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#whatelsecaniconfig">What else can I config?</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#executingcommands">Executing commands</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#advancedssitechniques">Advanced SSI techniques</a>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#settingvariables">Setting variables</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#conditionalexpressions">Conditional expressions</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li><a href="#conclusion">Conclusion</a></li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</ul>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<!-- INDEX END -->
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name=
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync"apachetutorial:introductiontoserversideincludes">Apache
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTutorial: Introduction to Server Side Includes</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<table border="1">
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<tr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<td valign="top"><strong>Related Modules</strong><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <a href="/mod/mod_include.html">mod_include</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href="/mod/mod_cgi.html">mod_cgi</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href="/mod/mod_expires.html">mod_expires</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </td>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<td valign="top"><strong>Related Directives</strong><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync <a href="/mod/core.html#options">Options</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href="/mod/mod_include.html#xbithack">XBitHack</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href="/mod/mod_mime.html#addtype">AddType</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href="/mod/mod_mime.html#addhandler">AddHandler</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<a href=
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync"/mod/mod_setenvif.html#BrowserMatchNoCase">BrowserMatchNoCase</a><br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync </td>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</tr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</table>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>This HOWTO first appeared in Apache Today
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync(http://www.apachetoday.com/) as a series of three articles. They
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncappear here by arrangement with ApacheToday and Internet.com.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>This article deals with Server Side Includes, usually called simply
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSSI. In this article, I'll talk about configuring your server to permit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncSSI, and introduce some basic SSI techniques for adding dynamic content
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncto your existing HTML pages.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>In the latter part of the article, we'll talk about some of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsomewhat more advanced things that can be done with SSI, such as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncconditional statements in your SSI directives.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="whataressi">What are SSI?</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>SSI (Server Side Includes) are directives that are placed in HTML
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncpages, and evaluated on the server while the pages are being served.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThey let you add dynamically generated content to an existing HTML
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncpage, without having to serve the entire page via a CGI program, or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncother dynamic technology.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>The decision of when to use SSI, and when to have your page entirely
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncgenerated by some program, is usually a matter of how much of the page
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncis static, and how much needs to be recalculated every time the page is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncserved. SSI is a great way to add small pieces of information, such as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe current time. But if a majority of your page is being generated at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe time that it is served, you need to look for some other
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsolution.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="configuringyourservertopermitssi">Configuring your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncserver to permit SSI</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>To permit SSI on your server, you must have the following directive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynceither in your <code>httpd.conf</code> file, or in a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>.htaccess</code> file:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Options +Includes
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>This tells Apache that you want to permit files to be parsed for SSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdirectives.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Not just any file is parsed for SSI directives. You have to tell
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncApache which files should be parsed. There are two ways to do this. You
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynccan tell Apache to parse any file with a particular file extension,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsuch as <code>.shtml</code>, with the following directives:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddType text/html .shtml
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;FilesMatch "\.shtml[.$]"&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SetOutputFilter INCLUDES<br>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;/FilesMatch&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>One disadvantage to this approach is that if you wanted to add SSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdirectives to an existing page, you would have to change the name of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthat page, and all links to that page, in order to give it a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>.shtml</code> extension, so that those directives would be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncexecuted.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>The other method is to use the <code>XBitHack</code> directive:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync XBitHack on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p><code>XBitHack</code> tells Apache to parse files for SSI directives
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncif they have the execute bit set. So, to add SSI directives to an
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncexisting page, rather than having to change the file name, you would
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncjust need to make the file executable using <code>chmod</code>.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync chmod +x pagename.html
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>A brief comment about what not to do. You'll occasionally see people
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncrecommending that you just tell Apache to parse all <code>.html</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfiles for SSI, so that you don't have to mess with <code>.shtml</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfile names. These folks have perhaps not heard about
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>XBitHack</code>. The thing to keep in mind is that, by doing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthis, you're requiring that Apache read through every single file that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncit sends out to clients, even if they don't contain any SSI directives.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis can slow things down quite a bit, and is not a good idea.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Of course, on Windows, there is no such thing as an execute bit to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncset, so that limits your options a little.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>In its default configuration, Apache does not send the last modified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdate or content length HTTP headers on SSI pages, because these values are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdifficult to calculate for dynamic content. This can prevent your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdocument from being cached, and result in slower perceived client
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncperformance. There are two ways to solve this:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<ol>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li>Use the <code>XBitHack Full</code> configuration. This tells
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncApache to determine the last modified date by looking only at the date
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncof the originally requested file, ignoring the modification date of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncany included files. </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<li>Use the directives provided by <a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchref="/mod/mod_expires.html">mod_expires</a> to set an explicit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncexpiration time on your files, thereby letting browsers and proxies
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncknow that it is acceptable to cache them. </li>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</ol>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="basicssidirectives">Basic SSI directives</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>SSI directives have the following syntax:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#element attribute=value attribute=value ... --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>It is formatted like an HTML comment, so if you don't have SSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynccorrectly enabled, the browser will ignore it, but it will still be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncvisible in the HTML source. If you have SSI correctly configured, the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdirective will be replaced with its results.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>The element can be one of a number of things, and we'll talk some
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmore about most of these in the next installment of this series. For
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncnow, here are some examples of what you can do with SSI</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h3><a name="today'sdate">Today's date</a></h3>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#echo var="DATE_LOCAL" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>The <code>echo</code> element just spits out the value of a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncvariable. There are a number of standard variables, which include the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhole set of environment variables that are available to CGI programs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncAlso, you can define your own variables with the <code>set</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncelement.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>If you don't like the format in which the date gets printed, you can
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncuse the <code>config</code> element, with a <code>timefmt</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncattribute, to modify that formatting.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#config timefmt="%A %B %d, %Y" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h3><a name="modificationdateofthefile">Modification date of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfile</a></h3>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This document last modified &lt;!--#flastmod file="index.html" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>This element is also subject to <code>timefmt</code> format
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncconfigurations.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h3><a name="includingtheresultsofacgiprogram">Including the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncresults of a CGI program</a></h3>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>This is one of the more common uses of SSI - to output the results
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncof a CGI program, such as everybody's favorite, a ``hit counter.''</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="additionalexamples">Additional examples</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Following are some specific examples of things you can do in your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncHTML documents with SSI.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="whenwasthisdocumentmodified">When was this document
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncmodified?</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Earlier, we mentioned that you could use SSI to inform the user when
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe document was most recently modified. However, the actual method for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncdoing that was left somewhat in question. The following code, placed in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncyour HTML document, will put such a time stamp on your page. Of course,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncyou will have to have SSI correctly enabled, as discussed above.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#config timefmt="%A %B %d, %Y" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file last modified &lt;!--#flastmod file="ssi.shtml" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Of course, you will need to replace the <code>ssi.shtml</code> with
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe actual name of the file that you're referring to. This can be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncinconvenient if you're just looking for a generic piece of code that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncyou can paste into any file, so you probably want to use the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>LAST_MODIFIED</code> variable instead:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#config timefmt="%D" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>For more details on the <code>timefmt</code> format, go to your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfavorite search site and look for <code>ctime</code>. The syntax is the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsame.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="includingastandardfooter">Including a standard
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfooter</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>If you are managing any site that is more than a few pages, you may
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfind that making changes to all those pages can be a real pain,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncparticularly if you are trying to maintain some kind of standard look
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncacross all those pages.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Using an include file for a header and/or a footer can reduce the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncburden of these updates. You just have to make one footer file, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthen include it into each page with the <code>include</code> SSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynccommand. The <code>include</code> element can determine what file to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncinclude with either the <code>file</code> attribute, or the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>virtual</code> attribute. The <code>file</code> attribute is a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfile path, <em>relative to the current directory</em>. That means that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncit cannot be an absolute file path (starting with /), nor can it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynccontain ../ as part of that path. The <code>virtual</code> attribute is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncprobably more useful, and should specify a URL relative to the document
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncbeing served. It can start with a /, but must be on the same server as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe file being served.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#include virtual="/footer.html" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>I'll frequently combine the last two things, putting a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>LAST_MODIFIED</code> directive inside a footer file to be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncincluded. SSI directives can be contained in the included file, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncincludes can be nested - that is, the included file can include another
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfile, and so on.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="whatelsecaniconfig">What else can I config?</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>In addition to being able to <code>config</code> the time format,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncyou can also <code>config</code> two other things.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Usually, when something goes wrong with your SSI directive, you get
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthe message</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync [an error occurred while processing this directive]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>If you want to change that message to something else, you can do so
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwith the <code>errmsg</code> attribute to the <code>config</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncelement:</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#config errmsg="[It appears that you don't know how to use SSI]" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Hopefully, end users will never see this message, because you will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchave resolved all the problems with your SSI directives before your
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsite goes live. (Right?)</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>And you can <code>config</code> the format in which file sizes are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncreturned with the <code>sizefmt</code> attribute. You can specify
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>bytes</code> for a full count in bytes, or <code>abbrev</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfor an abbreviated number in Kb or Mb, as appropriate.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="executingcommands">Executing commands</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>I expect that I'll have an article some time in the coming months
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncabout using SSI with small CGI programs. For now, here's something else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncthat you can do with the <code>exec</code> element. You can actually
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsynchave SSI execute a command using the shell (<code>/bin/sh</code>, to be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncprecise - or the DOS shell, if you're on Win32). The following, for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncexample, will give you a directory listing.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;pre&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#exec cmd="ls" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;/pre&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>or, on Windows</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;pre&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;!--#exec cmd="dir" --&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &lt;/pre&gt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync</pre>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>You might notice some strange formatting with this directive on
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWindows, because the output from <code>dir</code> contains the string
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync``&lt;<code>dir</code>&gt;'' in it, which confuses browsers.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<p>Note that this feature is exceedingly dangerous, as it will execute
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhatever code happens to be embedded in the <code>exec</code> tag. If
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncyou have any situation where users can edit content on your web pages,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncsuch as with a ``guestbook'', for example, make sure that you have this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfeature disabled. You can allow SSI, but not the <code>exec</code>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncfeature, with the <code>IncludesNOEXEC</code> argument to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<code>Options</code> directive.</p>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<hr>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync<h2><a name="advancedssitechniques">Advanced SSI techniques</a></h2>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
<p>In addition to spitting out content, Apache SSI gives you the option
of setting variables, and using those variables in comparisons and
conditionals.</p>
<h3><a name="caveat">Caveat</a></h3>
<p>Most of the features discussed in this article are only available to
you if you are running Apache 1.2 or later. Of course, if you are not
running Apache 1.2 or later, you need to upgrade immediately, if not
sooner. Go on. Do it now. We'll wait.</p>
<hr>
<h2><a name="settingvariables">Setting variables</a></h2>
<p>Using the <code>set</code> directive, you can set variables for
later use. We'll need this later in the discussion, so we'll talk about
it here. The syntax of this is as follows:</p>
<pre>
&lt;!--#set var="name" value="Rich" --&gt;
</pre>
<p>In addition to merely setting values literally like that, you can
use any other variable, including, for example, environment variables,
or some of the variables we discussed in the last article (like
<code>LAST_MODIFIED</code>, for example) to give values to your
variables. You will specify that something is a variable, rather than a
literal string, by using the dollar sign ($) before the name of the
variable.</p>
<pre>
&lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
</pre>
<p>To put a literal dollar sign into the value of your variable, you
need to escape the dollar sign with a backslash.</p>
<pre>
&lt;!--#set var="cost" value="\$100" --&gt;
</pre>
<p>Finally, if you want to put a variable in the midst of a longer
string, and there's a chance that the name of the variable will run up
against some other characters, and thus be confused with those
characters, you can place the name of the variable in braces, to remove
this confusion. (It's hard to come up with a really good example of
this, but hopefully you'll get the point.)</p>
<pre>
&lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
</pre>
<hr>
<h2><a name="conditionalexpressions">Conditional expressions</a></h2>
<p>Now that we have variables, and are able to set and compare their
values, we can use them to express conditionals. This lets SSI be a
tiny programming language of sorts. <code>mod_include</code> provides
an <code>if</code>, <code>elif</code>, <code>else</code>,
<code>endif</code> structure for building conditional statements. This
allows you to effectively generate multiple logical pages out of one
actual page.</p>
<p>The structure of this conditional construct is:</p>
<pre>
&lt;!--#if expr="test_condition" --&gt;
&lt;!--#elif expr="test_condition" --&gt;
&lt;!--#else --&gt;
&lt;!--#endif --&gt;
</pre>
<p>A <em>test_condition</em> can be any sort of logical comparison -
either comparing values to one another, or testing the ``truth'' of a
particular value. (A given string is true if it is nonempty.) For a
full list of the comparison operators available to you, see the
<code>mod_include</code> documentation. Here are some examples of how
one might use this construct.</p>
<p>In your configuration file, you could put the following line:</p>
<pre>
BrowserMatchNoCase macintosh Mac
BrowserMatchNoCase MSIE InternetExplorer
</pre>
<p>This will set environment variables ``Mac'' and ``InternetExplorer''
to true, if the client is running Internet Explorer on a Macintosh.</p>
<p>Then, in your SSI-enabled document, you might do the following:</p>
<pre>
&lt;!--#if expr="${Mac} &amp;&amp; ${InternetExplorer}" --&gt;
Apologetic text goes here
&lt;!--#else --&gt;
Cool JavaScript code goes here
&lt;!--#endif --&gt;
</pre>
<p>Not that I have anything against IE on Macs - I just struggled for a
few hours last week trying to get some JavaScript working on IE on a
Mac, when it was working everywhere else. The above was the interim
workaround.</p>
<p>Any other variable (either ones that you define, or normal
environment variables) can be used in conditional statements. With
Apache's ability to set environment variables with the
<code>SetEnvIf</code> directives, and other related directives, this
functionality can let you do some pretty involved dynamic stuff without
ever resorting to CGI.</p>
<hr>
<h2><a name="conclusion">Conclusion</a></h2>
<p>SSI is certainly not a replacement for CGI, or other technologies
used for generating dynamic web pages. But it is a great way to add
small amounts of dynamic content to pages, without doing a lot of extra
work.</p>
</body>
</html>