| <?xml version="1.0" encoding="ISO-8859-1"?> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!-- |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| This file is generated from xml source: DO NOT EDIT |
| XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
| --> |
| <title>Apache Tutorial: Introduction to Server Side Includes - Apache HTTP Server</title> |
| <link href="../style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" /> |
| <link href="../style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" /> |
| <link href="../style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /> |
| <link href="../images/favicon.ico" rel="shortcut icon" /></head> |
| <body id="manual-page"><div id="page-header"> |
| <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p> |
| <p class="apache">Apache HTTP Server Version 2.0</p> |
| <img alt="" src="../images/feather.gif" /></div> |
| <div class="up"><a href="./"><img title="<-" alt="<-" src="../images/left.gif" /></a></div> |
| <div id="path"> |
| <a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs-project/">Documentation</a> > <a href="../">Version 2.0</a> > <a href="./">How-To / Tutorials</a></div><div id="page-content"><div id="preamble"><h1>Apache Tutorial: Introduction to Server Side Includes</h1> |
| <p>Server-side includes provide a means to add dynamic content to |
| existing HTML documents.</p> |
| </div> |
| <div id="quickview"><ul id="toc"><li><img alt="" src="../images/down.gif" /> <a href="#related">Introduction</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#what">What are SSI?</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#configuring">Configuring your server to permit SSI</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#basic">Basic SSI directives</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#additionalexamples">Additional examples</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#config">What else can I config?</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#exec">Executing commands</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#advanced">Advanced SSI techniques</a></li> |
| <li><img alt="" src="../images/down.gif" /> <a href="#conclusion">Conclusion</a></li> |
| </ul></div> |
| <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="related" id="related">Introduction</a></h2> |
| <table class="related"><tr><th>Related Modules</th><th>Related Directives</th></tr><tr><td><ul><li><code class="module"><a href="../mod/mod_include.html">mod_include</a></code></li><li><code class="module"><a href="../mod/mod_cgi.html">mod_cgi</a></code></li><li><code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code></li></ul></td><td><ul><li><code class="directive"><a href="../mod/core.html#options">Options</a></code></li><li><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code></li><li><code class="directive"><a href="../mod/mod_mime.html#addtype">AddType</a></code></li><li><code class="directive"><a href="../mod/core.html#setoutputfilter">SetOutputFilter</a></code></li><li><code class="directive"><a href="../mod/mod_setenvif.html#browsermatchnocase">BrowserMatchNoCase</a></code></li></ul></td></tr></table> |
| |
| <p>This article deals with Server Side Includes, usually called |
| simply SSI. In this article, I'll talk about configuring your |
| server to permit SSI, and introduce some basic SSI techniques |
| for adding dynamic content to your existing HTML pages.</p> |
| |
| <p>In the latter part of the article, we'll talk about some of |
| the somewhat more advanced things that can be done with SSI, |
| such as conditional statements in your SSI directives.</p> |
| |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="what" id="what">What are SSI?</a></h2> |
| |
| <p>SSI (Server Side Includes) are directives that are placed in |
| HTML pages, and evaluated on the server while the pages are |
| being served. They let you add dynamically generated content to |
| an existing HTML page, without having to serve the entire page |
| via a CGI program, or other dynamic technology.</p> |
| |
| <p>The decision of when to use SSI, and when to have your page |
| entirely generated by some program, is usually a matter of how |
| much of the page is static, and how much needs to be |
| recalculated every time the page is served. SSI is a great way |
| to add small pieces of information, such as the current time. |
| But if a majority of your page is being generated at the time |
| that it is served, you need to look for some other |
| solution.</p> |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="configuring" id="configuring">Configuring your server to permit SSI</a></h2> |
| |
| |
| <p>To permit SSI on your server, you must have the following |
| directive either in your <code>httpd.conf</code> file, or in a |
| <code>.htaccess</code> file:</p> |
| <div class="example"><p><code> |
| Options +Includes |
| </code></p></div> |
| |
| <p>This tells Apache that you want to permit files to be parsed |
| for SSI directives. Note that most configurations contain |
| multiple <code class="directive"><a href="../mod/core.html#options">Options</a></code> directives |
| that can override each other. You will probably need to apply the |
| <code>Options</code> to the specific directory where you want SSI |
| enabled in order to assure that it gets evaluated last.</p> |
| |
| <p>Not just any file is parsed for SSI directives. You have to |
| tell Apache which files should be parsed. There are two ways to |
| do this. You can tell Apache to parse any file with a |
| particular file extension, such as <code>.shtml</code>, with |
| the following directives:</p> |
| <div class="example"><p><code> |
| AddType text/html .shtml<br /> |
| AddOutputFilter INCLUDES .shtml |
| </code></p></div> |
| |
| <p>One disadvantage to this approach is that if you wanted to |
| add SSI directives to an existing page, you would have to |
| change the name of that page, and all links to that page, in |
| order to give it a <code>.shtml</code> extension, so that those |
| directives would be executed.</p> |
| |
| <p>The other method is to use the <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> directive:</p> |
| <div class="example"><p><code> |
| XBitHack on |
| </code></p></div> |
| |
| <p><code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code> |
| tells Apache to parse files for SSI |
| directives if they have the execute bit set. So, to add SSI |
| directives to an existing page, rather than having to change |
| the file name, you would just need to make the file executable |
| using <code>chmod</code>.</p> |
| <div class="example"><p><code> |
| chmod +x pagename.html |
| </code></p></div> |
| |
| <p>A brief comment about what not to do. You'll occasionally |
| see people recommending that you just tell Apache to parse all |
| <code>.html</code> files for SSI, so that you don't have to |
| mess with <code>.shtml</code> file names. These folks have |
| perhaps not heard about <code class="directive"><a href="../mod/mod_include.html#xbithack">XBitHack</a></code>. The thing to |
| keep in mind is that, by doing this, you're requiring that |
| Apache read through every single file that it sends out to |
| clients, even if they don't contain any SSI directives. This |
| can slow things down quite a bit, and is not a good idea.</p> |
| |
| <p>Of course, on Windows, there is no such thing as an execute |
| bit to set, so that limits your options a little.</p> |
| |
| <p>In its default configuration, Apache does not send the last |
| modified date or content length HTTP headers on SSI pages, |
| because these values are difficult to calculate for dynamic |
| content. This can prevent your document from being cached, and |
| result in slower perceived client performance. There are two |
| ways to solve this:</p> |
| |
| <ol> |
| <li>Use the <code>XBitHack Full</code> configuration. This |
| tells Apache to determine the last modified date by looking |
| only at the date of the originally requested file, ignoring |
| the modification date of any included files.</li> |
| |
| <li>Use the directives provided by |
| <code class="module"><a href="../mod/mod_expires.html">mod_expires</a></code> to set an explicit expiration |
| time on your files, thereby letting browsers and proxies |
| know that it is acceptable to cache them.</li> |
| </ol> |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="basic" id="basic">Basic SSI directives</a></h2> |
| |
| <p>SSI directives have the following syntax:</p> |
| <div class="example"><p><code> |
| <!--#element attribute=value attribute=value ... --> |
| </code></p></div> |
| |
| <p>It is formatted like an HTML comment, so if you don't have |
| SSI correctly enabled, the browser will ignore it, but it will |
| still be visible in the HTML source. If you have SSI correctly |
| configured, the directive will be replaced with its |
| results.</p> |
| |
| <p>The element can be one of a number of things, and we'll talk |
| some more about most of these in the next installment of this |
| series. For now, here are some examples of what you can do with |
| SSI</p> |
| |
| <h3><a name="todaysdate" id="todaysdate">Today's date</a></h3> |
| |
| <div class="example"><p><code> |
| <!--#echo var="DATE_LOCAL" --> |
| </code></p></div> |
| |
| <p>The <code>echo</code> element just spits out the value of a |
| variable. There are a number of standard variables, which |
| include the whole set of environment variables that are |
| available to CGI programs. Also, you can define your own |
| variables with the <code>set</code> element.</p> |
| |
| <p>If you don't like the format in which the date gets printed, |
| you can use the <code>config</code> element, with a |
| <code>timefmt</code> attribute, to modify that formatting.</p> |
| |
| <div class="example"><p><code> |
| <!--#config timefmt="%A %B %d, %Y" --><br /> |
| Today is <!--#echo var="DATE_LOCAL" --> |
| </code></p></div> |
| |
| |
| <h3><a name="lastmodified" id="lastmodified">Modification date of the file</a></h3> |
| |
| <div class="example"><p><code> |
| This document last modified <!--#flastmod file="index.html" --> |
| </code></p></div> |
| |
| <p>This element is also subject to <code>timefmt</code> format |
| configurations.</p> |
| |
| |
| <h3><a name="cgi" id="cgi">Including the results of a CGI program</a></h3> |
| |
| <p>This is one of the more common uses of SSI - to output the |
| results of a CGI program, such as everybody's favorite, a ``hit |
| counter.''</p> |
| |
| <div class="example"><p><code> |
| <!--#include virtual="/cgi-bin/counter.pl" --> |
| </code></p></div> |
| |
| |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="additionalexamples" id="additionalexamples">Additional examples</a></h2> |
| |
| |
| <p>Following are some specific examples of things you can do in |
| your HTML documents with SSI.</p> |
| |
| <h3><a name="docmodified" id="docmodified">When was this document |
| modified?</a></h3> |
| |
| <p>Earlier, we mentioned that you could use SSI to inform the |
| user when the document was most recently modified. However, the |
| actual method for doing that was left somewhat in question. The |
| following code, placed in your HTML document, will put such a |
| time stamp on your page. Of course, you will have to have SSI |
| correctly enabled, as discussed above.</p> |
| <div class="example"><p><code> |
| <!--#config timefmt="%A %B %d, %Y" --><br /> |
| This file last modified <!--#flastmod file="ssi.shtml" --> |
| </code></p></div> |
| |
| <p>Of course, you will need to replace the |
| <code>ssi.shtml</code> with the actual name of the file that |
| you're referring to. This can be inconvenient if you're just |
| looking for a generic piece of code that you can paste into any |
| file, so you probably want to use the |
| <code>LAST_MODIFIED</code> variable instead:</p> |
| <div class="example"><p><code> |
| <!--#config timefmt="%D" --><br /> |
| This file last modified <!--#echo var="LAST_MODIFIED" --> |
| </code></p></div> |
| |
| <p>For more details on the <code>timefmt</code> format, go to |
| your favorite search site and look for <code>strftime</code>. The |
| syntax is the same.</p> |
| |
| |
| <h3><a name="standard-footer" id="standard-footer">Including a standard footer</a></h3> |
| |
| |
| <p>If you are managing any site that is more than a few pages, |
| you may find that making changes to all those pages can be a |
| real pain, particularly if you are trying to maintain some kind |
| of standard look across all those pages.</p> |
| |
| <p>Using an include file for a header and/or a footer can |
| reduce the burden of these updates. You just have to make one |
| footer file, and then include it into each page with the |
| <code>include</code> SSI command. The <code>include</code> |
| element can determine what file to include with either the |
| <code>file</code> attribute, or the <code>virtual</code> |
| attribute. The <code>file</code> attribute is a file path, |
| <em>relative to the current directory</em>. That means that it |
| cannot be an absolute file path (starting with /), nor can it |
| contain ../ as part of that path. The <code>virtual</code> |
| attribute is probably more useful, and should specify a URL |
| relative to the document being served. It can start with a /, |
| but must be on the same server as the file being served.</p> |
| <div class="example"><p><code> |
| <!--#include virtual="/footer.html" --> |
| </code></p></div> |
| |
| <p>I'll frequently combine the last two things, putting a |
| <code>LAST_MODIFIED</code> directive inside a footer file to be |
| included. SSI directives can be contained in the included file, |
| and includes can be nested - that is, the included file can |
| include another file, and so on.</p> |
| |
| |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="config" id="config">What else can I config?</a></h2> |
| |
| |
| <p>In addition to being able to <code>config</code> the time |
| format, you can also <code>config</code> two other things.</p> |
| |
| <p>Usually, when something goes wrong with your SSI directive, |
| you get the message</p> |
| <div class="example"><p><code> |
| [an error occurred while processing this directive] |
| </code></p></div> |
| |
| <p>If you want to change that message to something else, you |
| can do so with the <code>errmsg</code> attribute to the |
| <code>config</code> element:</p> |
| <div class="example"><p><code> |
| <!--#config errmsg="[It appears that you don't know how to use SSI]" --> |
| </code></p></div> |
| |
| <p>Hopefully, end users will never see this message, because |
| you will have resolved all the problems with your SSI |
| directives before your site goes live. (Right?)</p> |
| |
| <p>And you can <code>config</code> the format in which file |
| sizes are returned with the <code>sizefmt</code> attribute. You |
| can specify <code>bytes</code> for a full count in bytes, or |
| <code>abbrev</code> for an abbreviated number in Kb or Mb, as |
| appropriate.</p> |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="exec" id="exec">Executing commands</a></h2> |
| |
| |
| <p>I expect that I'll have an article some time in the coming |
| months about using SSI with small CGI programs. For now, here's |
| something else that you can do with the <code>exec</code> |
| element. You can actually have SSI execute a command using the |
| shell (<code>/bin/sh</code>, to be precise - or the DOS shell, |
| if you're on Win32). The following, for example, will give you |
| a directory listing.</p> |
| <div class="example"><p><code> |
| <pre><br /> |
| <!--#exec cmd="ls" --><br /> |
| </pre> |
| </code></p></div> |
| |
| <p>or, on Windows</p> |
| <div class="example"><p><code> |
| <pre><br /> |
| <!--#exec cmd="dir" --><br /> |
| </pre> |
| </code></p></div> |
| |
| <p>You might notice some strange formatting with this directive |
| on Windows, because the output from <code>dir</code> contains |
| the string ``<<code>dir</code>>'' in it, which confuses |
| browsers.</p> |
| |
| <p>Note that this feature is exceedingly dangerous, as it will |
| execute whatever code happens to be embedded in the |
| <code>exec</code> tag. If you have any situation where users |
| can edit content on your web pages, such as with a |
| ``guestbook'', for example, make sure that you have this |
| feature disabled. You can allow SSI, but not the |
| <code>exec</code> feature, with the <code>IncludesNOEXEC</code> |
| argument to the <code>Options</code> directive.</p> |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="advanced" id="advanced">Advanced SSI techniques</a></h2> |
| |
| |
| <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" id="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> |
| |
| |
| <h3><a name="variables" id="variables">Setting variables</a></h3> |
| |
| <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> |
| <div class="example"><p><code> |
| <!--#set var="name" value="Rich" --> |
| </code></p></div> |
| |
| <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> |
| <div class="example"><p><code> |
| <!--#set var="modified" value="$LAST_MODIFIED" --> |
| </code></p></div> |
| |
| <p>To put a literal dollar sign into the value of your |
| variable, you need to escape the dollar sign with a |
| backslash.</p> |
| <div class="example"><p><code> |
| <!--#set var="cost" value="\$100" --> |
| </code></p></div> |
| |
| <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> |
| <div class="example"><p><code> |
| <!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --> |
| </code></p></div> |
| |
| |
| <h3><a name="conditional" id="conditional">Conditional expressions</a></h3> |
| |
| |
| <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 class="module"><a href="../mod/mod_include.html">mod_include</a></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> |
| <div class="example"><p><code> |
| <!--#if expr="test_condition" --><br /> |
| <!--#elif expr="test_condition" --><br /> |
| <!--#else --><br /> |
| <!--#endif --> |
| </code></p></div> |
| |
| <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 class="module"><a href="../mod/mod_include.html">mod_include</a></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> |
| <div class="example"><p><code> |
| BrowserMatchNoCase macintosh Mac<br /> |
| BrowserMatchNoCase MSIE InternetExplorer |
| </code></p></div> |
| |
| <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> |
| <div class="example"><p><code> |
| <!--#if expr="${Mac} && ${InternetExplorer}" --><br /> |
| Apologetic text goes here<br /> |
| <!--#else --><br /> |
| Cool JavaScript code goes here<br /> |
| <!--#endif --> |
| </code></p></div> |
| |
| <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> |
| |
| </div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
| <div class="section"> |
| <h2><a name="conclusion" id="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> |
| </div></div> |
| <div id="footer"> |
| <p class="apache">Maintained by the <a href="http://httpd.apache.org/docs-project/">Apache HTTP Server Documentation Project</a></p> |
| <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div> |
| </body></html> |