]> granicus.if.org Git - apache/blob - docs/manual/howto/ssi.html.en
Correct SSI time format reference.
[apache] / docs / manual / howto / ssi.html.en
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4 <html xmlns="http://www.w3.org/1999/xhtml">
5   <head>
6     <meta name="generator" content="HTML Tidy, see www.w3.org" />
7
8     <title>Apache Tutorial: Introduction to Server Side
9     Includes</title>
10     <link rev="made" href="mailto:rbowen@rcbowen.com" />
11   </head>
12   <!-- Background white, links blue (unvisited), navy (visited), red (active) -->
13
14   <body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
15   vlink="#000080" alink="#FF0000">
16     <!--#include virtual="header.html" -->
17
18     <h1 align="CENTER">Apache Tutorial: Introduction to Server Side
19     Includes</h1>
20     <a id="__index__" name="__index__"></a> <!-- INDEX BEGIN -->
21      
22
23     <ul>
24       <li><a
25       href="#apachetutorial:introductiontoserversideincludes">Apache
26       Tutorial: Introduction to Server Side Includes</a></li>
27
28       <li><a href="#whataressi">What are SSI?</a></li>
29
30       <li><a href="#configuringyourservertopermitssi">Configuring
31       your server to permit SSI</a></li>
32
33       <li>
34         <a href="#basicssidirectives">Basic SSI directives</a> 
35
36         <ul>
37           <li><a href="#today'sdate">Today's date</a></li>
38
39           <li><a href="#modificationdateofthefile">Modification
40           date of the file</a></li>
41
42           <li><a href="#includingtheresultsofacgiprogram">Including
43           the results of a CGI program</a></li>
44         </ul>
45       </li>
46
47       <li>
48         <a href="#additionalexamples">Additional examples</a> 
49
50         <ul>
51           <li><a href="#whenwasthisdocumentmodified">When was this
52           document modified?</a></li>
53
54           <li><a href="#includingastandardfooter">Including a
55           standard footer</a></li>
56
57           <li><a href="#whatelsecaniconfig">What else can I
58           config?</a></li>
59
60           <li><a href="#executingcommands">Executing
61           commands</a></li>
62         </ul>
63       </li>
64
65       <li>
66         <a href="#advancedssitechniques">Advanced SSI
67         techniques</a> 
68
69         <ul>
70           <li><a href="#settingvariables">Setting
71           variables</a></li>
72
73           <li><a href="#conditionalexpressions">Conditional
74           expressions</a></li>
75         </ul>
76       </li>
77
78       <li><a href="#conclusion">Conclusion</a></li>
79     </ul>
80     <!-- INDEX END -->
81     <hr />
82
83     <h2><a id="apachetutorial:introductiontoserversideincludes"
84     name="apachetutorial:introductiontoserversideincludes">Apache
85     Tutorial: Introduction to Server Side Includes</a></h2>
86
87     <table border="1">
88       <tr>
89         <td valign="top"><strong>Related Modules</strong><br />
90          <br />
91          <a href="../mod/mod_include.html">mod_include</a><br />
92          <a href="../mod/mod_cgi.html">mod_cgi</a><br />
93          <a href="../mod/mod_expires.html">mod_expires</a><br />
94          </td>
95
96         <td valign="top"><strong>Related Directives</strong><br />
97          <br />
98          <a href="../mod/core.html#options">Options</a><br />
99          <a
100         href="../mod/mod_include.html#xbithack">XBitHack</a><br />
101          <a href="../mod/mod_mime.html#addtype">AddType</a><br />
102          <a
103         href="../mod/core.html#setoutputfilter">SetOutputFilter</a><br />
104          <a
105         href="../mod/mod_setenvif.html#BrowserMatchNoCase">BrowserMatchNoCase</a><br />
106          </td>
107       </tr>
108     </table>
109
110     <p>This article deals with Server Side Includes, usually called
111     simply SSI. In this article, I'll talk about configuring your
112     server to permit SSI, and introduce some basic SSI techniques
113     for adding dynamic content to your existing HTML pages.</p>
114
115     <p>In the latter part of the article, we'll talk about some of
116     the somewhat more advanced things that can be done with SSI,
117     such as conditional statements in your SSI directives.</p>
118     <hr />
119
120     <h2><a id="whataressi" name="whataressi">What are SSI?</a></h2>
121
122     <p>SSI (Server Side Includes) are directives that are placed in
123     HTML pages, and evaluated on the server while the pages are
124     being served. They let you add dynamically generated content to
125     an existing HTML page, without having to serve the entire page
126     via a CGI program, or other dynamic technology.</p>
127
128     <p>The decision of when to use SSI, and when to have your page
129     entirely generated by some program, is usually a matter of how
130     much of the page is static, and how much needs to be
131     recalculated every time the page is served. SSI is a great way
132     to add small pieces of information, such as the current time.
133     But if a majority of your page is being generated at the time
134     that it is served, you need to look for some other
135     solution.</p>
136     <hr />
137
138     <h2><a id="configuringyourservertopermitssi"
139     name="configuringyourservertopermitssi">Configuring your server
140     to permit SSI</a></h2>
141
142     <p>To permit SSI on your server, you must have the following
143     directive either in your <code>httpd.conf</code> file, or in a
144     <code>.htaccess</code> file:</p>
145 <pre>
146         Options +Includes
147 </pre>
148
149     <p>This tells Apache that you want to permit files to be parsed
150     for SSI directives.  Note that most configurations contain
151     multiple <a href="../mod/core.html#options">Options</a> directives
152     that can override each other.  You will probably need to apply the
153     <code>Options</code> to the specific directory where you want SSI
154     enabled in order to assure that it gets evaluated last.</p>
155
156     <p>Not just any file is parsed for SSI directives. You have to
157     tell Apache which files should be parsed. There are two ways to
158     do this. You can tell Apache to parse any file with a
159     particular file extension, such as <code>.shtml</code>, with
160     the following directives:</p>
161 <pre>
162         AddType text/html .shtml
163         AddOutputFilter INCLUDES .shtml
164 </pre>
165
166     <p>One disadvantage to this approach is that if you wanted to
167     add SSI directives to an existing page, you would have to
168     change the name of that page, and all links to that page, in
169     order to give it a <code>.shtml</code> extension, so that those
170     directives would be executed.</p>
171
172     <p>The other method is to use the <code>XBitHack</code>
173     directive:</p>
174 <pre>
175         XBitHack on
176 </pre>
177
178     <p><code>XBitHack</code> tells Apache to parse files for SSI
179     directives if they have the execute bit set. So, to add SSI
180     directives to an existing page, rather than having to change
181     the file name, you would just need to make the file executable
182     using <code>chmod</code>.</p>
183 <pre>
184         chmod +x pagename.html
185 </pre>
186
187     <p>A brief comment about what not to do. You'll occasionally
188     see people recommending that you just tell Apache to parse all
189     <code>.html</code> files for SSI, so that you don't have to
190     mess with <code>.shtml</code> file names. These folks have
191     perhaps not heard about <code>XBitHack</code>. The thing to
192     keep in mind is that, by doing this, you're requiring that
193     Apache read through every single file that it sends out to
194     clients, even if they don't contain any SSI directives. This
195     can slow things down quite a bit, and is not a good idea.</p>
196
197     <p>Of course, on Windows, there is no such thing as an execute
198     bit to set, so that limits your options a little.</p>
199
200     <p>In its default configuration, Apache does not send the last
201     modified date or content length HTTP headers on SSI pages,
202     because these values are difficult to calculate for dynamic
203     content. This can prevent your document from being cached, and
204     result in slower perceived client performance. There are two
205     ways to solve this:</p>
206
207     <ol>
208       <li>Use the <code>XBitHack Full</code> configuration. This
209       tells Apache to determine the last modified date by looking
210       only at the date of the originally requested file, ignoring
211       the modification date of any included files.</li>
212
213       <li>Use the directives provided by <a
214       href="../mod/mod_expires.html">mod_expires</a> to set an
215       explicit expiration time on your files, thereby letting
216       browsers and proxies know that it is acceptable to cache
217       them.</li>
218     </ol>
219     <hr />
220
221     <h2><a id="basicssidirectives" name="basicssidirectives">Basic
222     SSI directives</a></h2>
223
224     <p>SSI directives have the following syntax:</p>
225 <pre>
226         &lt;!--#element attribute=value attribute=value ... --&gt;
227 </pre>
228
229     <p>It is formatted like an HTML comment, so if you don't have
230     SSI correctly enabled, the browser will ignore it, but it will
231     still be visible in the HTML source. If you have SSI correctly
232     configured, the directive will be replaced with its
233     results.</p>
234
235     <p>The element can be one of a number of things, and we'll talk
236     some more about most of these in the next installment of this
237     series. For now, here are some examples of what you can do with
238     SSI</p>
239
240     <h3><a id="today'sdate" name="today'sdate">Today's
241     date</a></h3>
242 <pre>
243         &lt;!--#echo var="DATE_LOCAL" --&gt;
244 </pre>
245
246     <p>The <code>echo</code> element just spits out the value of a
247     variable. There are a number of standard variables, which
248     include the whole set of environment variables that are
249     available to CGI programs. Also, you can define your own
250     variables with the <code>set</code> element.</p>
251
252     <p>If you don't like the format in which the date gets printed,
253     you can use the <code>config</code> element, with a
254     <code>timefmt</code> attribute, to modify that formatting.</p>
255 <pre>
256         &lt;!--#config timefmt="%A %B %d, %Y" --&gt;
257         Today is &lt;!--#echo var="DATE_LOCAL" --&gt;
258 </pre>
259
260     <h3><a id="modificationdateofthefile"
261     name="modificationdateofthefile">Modification date of the
262     file</a></h3>
263 <pre>
264         This document last modified &lt;!--#flastmod file="index.html" --&gt;
265 </pre>
266
267     <p>This element is also subject to <code>timefmt</code> format
268     configurations.</p>
269
270     <h3><a id="includingtheresultsofacgiprogram"
271     name="includingtheresultsofacgiprogram">Including the results
272     of a CGI program</a></h3>
273
274     <p>This is one of the more common uses of SSI - to output the
275     results of a CGI program, such as everybody's favorite, a ``hit
276     counter.''</p>
277 <pre>
278         &lt;!--#include virtual="/cgi-bin/counter.pl" --&gt;
279 </pre>
280     <hr />
281
282     <h2><a id="additionalexamples"
283     name="additionalexamples">Additional examples</a></h2>
284
285     <p>Following are some specific examples of things you can do in
286     your HTML documents with SSI.</p>
287     <hr />
288
289     <h2><a id="whenwasthisdocumentmodified"
290     name="whenwasthisdocumentmodified">When was this document
291     modified?</a></h2>
292
293     <p>Earlier, we mentioned that you could use SSI to inform the
294     user when the document was most recently modified. However, the
295     actual method for doing that was left somewhat in question. The
296     following code, placed in your HTML document, will put such a
297     time stamp on your page. Of course, you will have to have SSI
298     correctly enabled, as discussed above.</p>
299 <pre>
300         &lt;!--#config timefmt="%A %B %d, %Y" --&gt;
301         This file last modified &lt;!--#flastmod file="ssi.shtml" --&gt;
302 </pre>
303
304     <p>Of course, you will need to replace the
305     <code>ssi.shtml</code> with the actual name of the file that
306     you're referring to. This can be inconvenient if you're just
307     looking for a generic piece of code that you can paste into any
308     file, so you probably want to use the
309     <code>LAST_MODIFIED</code> variable instead:</p>
310 <pre>
311         &lt;!--#config timefmt="%D" --&gt;
312         This file last modified &lt;!--#echo var="LAST_MODIFIED" --&gt;
313 </pre>
314
315     <p>For more details on the <code>timefmt</code> format, go to
316     your favorite search site and look for <code>strftime</code>. The
317     syntax is the same.</p>
318     <hr />
319
320     <h2><a id="includingastandardfooter"
321     name="includingastandardfooter">Including a standard
322     footer</a></h2>
323
324     <p>If you are managing any site that is more than a few pages,
325     you may find that making changes to all those pages can be a
326     real pain, particularly if you are trying to maintain some kind
327     of standard look across all those pages.</p>
328
329     <p>Using an include file for a header and/or a footer can
330     reduce the burden of these updates. You just have to make one
331     footer file, and then include it into each page with the
332     <code>include</code> SSI command. The <code>include</code>
333     element can determine what file to include with either the
334     <code>file</code> attribute, or the <code>virtual</code>
335     attribute. The <code>file</code> attribute is a file path,
336     <em>relative to the current directory</em>. That means that it
337     cannot be an absolute file path (starting with /), nor can it
338     contain ../ as part of that path. The <code>virtual</code>
339     attribute is probably more useful, and should specify a URL
340     relative to the document being served. It can start with a /,
341     but must be on the same server as the file being served.</p>
342 <pre>
343         &lt;!--#include virtual="/footer.html" --&gt;
344 </pre>
345
346     <p>I'll frequently combine the last two things, putting a
347     <code>LAST_MODIFIED</code> directive inside a footer file to be
348     included. SSI directives can be contained in the included file,
349     and includes can be nested - that is, the included file can
350     include another file, and so on.</p>
351     <hr />
352
353     <h2><a id="whatelsecaniconfig" name="whatelsecaniconfig">What
354     else can I config?</a></h2>
355
356     <p>In addition to being able to <code>config</code> the time
357     format, you can also <code>config</code> two other things.</p>
358
359     <p>Usually, when something goes wrong with your SSI directive,
360     you get the message</p>
361 <pre>
362         [an error occurred while processing this directive]
363 </pre>
364
365     <p>If you want to change that message to something else, you
366     can do so with the <code>errmsg</code> attribute to the
367     <code>config</code> element:</p>
368 <pre>
369         &lt;!--#config errmsg="[It appears that you don't know how to use SSI]" --&gt;
370 </pre>
371
372     <p>Hopefully, end users will never see this message, because
373     you will have resolved all the problems with your SSI
374     directives before your site goes live. (Right?)</p>
375
376     <p>And you can <code>config</code> the format in which file
377     sizes are returned with the <code>sizefmt</code> attribute. You
378     can specify <code>bytes</code> for a full count in bytes, or
379     <code>abbrev</code> for an abbreviated number in Kb or Mb, as
380     appropriate.</p>
381     <hr />
382
383     <h2><a id="executingcommands"
384     name="executingcommands">Executing commands</a></h2>
385
386     <p>I expect that I'll have an article some time in the coming
387     months about using SSI with small CGI programs. For now, here's
388     something else that you can do with the <code>exec</code>
389     element. You can actually have SSI execute a command using the
390     shell (<code>/bin/sh</code>, to be precise - or the DOS shell,
391     if you're on Win32). The following, for example, will give you
392     a directory listing.</p>
393 <pre>
394         &lt;pre&gt;
395         &lt;!--#exec cmd="ls" --&gt;
396         &lt;/pre&gt;
397 </pre>
398
399     <p>or, on Windows</p>
400 <pre>
401         &lt;pre&gt;
402         &lt;!--#exec cmd="dir" --&gt;
403         &lt;/pre&gt;
404 </pre>
405
406     <p>You might notice some strange formatting with this directive
407     on Windows, because the output from <code>dir</code> contains
408     the string ``&lt;<code>dir</code>&gt;'' in it, which confuses
409     browsers.</p>
410
411     <p>Note that this feature is exceedingly dangerous, as it will
412     execute whatever code happens to be embedded in the
413     <code>exec</code> tag. If you have any situation where users
414     can edit content on your web pages, such as with a
415     ``guestbook'', for example, make sure that you have this
416     feature disabled. You can allow SSI, but not the
417     <code>exec</code> feature, with the <code>IncludesNOEXEC</code>
418     argument to the <code>Options</code> directive.</p>
419     <hr />
420
421     <h2><a id="advancedssitechniques"
422     name="advancedssitechniques">Advanced SSI techniques</a></h2>
423
424     <p>In addition to spitting out content, Apache SSI gives you
425     the option of setting variables, and using those variables in
426     comparisons and conditionals.</p>
427
428     <h3><a id="caveat" name="caveat">Caveat</a></h3>
429
430     <p>Most of the features discussed in this article are only
431     available to you if you are running Apache 1.2 or later. Of
432     course, if you are not running Apache 1.2 or later, you need to
433     upgrade immediately, if not sooner. Go on. Do it now. We'll
434     wait.</p>
435     <hr />
436
437     <h2><a id="settingvariables" name="settingvariables">Setting
438     variables</a></h2>
439
440     <p>Using the <code>set</code> directive, you can set variables
441     for later use. We'll need this later in the discussion, so
442     we'll talk about it here. The syntax of this is as follows:</p>
443 <pre>
444         &lt;!--#set var="name" value="Rich" --&gt;
445 </pre>
446
447     <p>In addition to merely setting values literally like that,
448     you can use any other variable, including, for example,
449     environment variables, or some of the variables we discussed in
450     the last article (like <code>LAST_MODIFIED</code>, for example)
451     to give values to your variables. You will specify that
452     something is a variable, rather than a literal string, by using
453     the dollar sign ($) before the name of the variable.</p>
454 <pre>
455         &lt;!--#set var="modified" value="$LAST_MODIFIED" --&gt;
456 </pre>
457
458     <p>To put a literal dollar sign into the value of your
459     variable, you need to escape the dollar sign with a
460     backslash.</p>
461 <pre>
462         &lt;!--#set var="cost" value="\$100" --&gt;
463 </pre>
464
465     <p>Finally, if you want to put a variable in the midst of a
466     longer string, and there's a chance that the name of the
467     variable will run up against some other characters, and thus be
468     confused with those characters, you can place the name of the
469     variable in braces, to remove this confusion. (It's hard to
470     come up with a really good example of this, but hopefully
471     you'll get the point.)</p>
472 <pre>
473         &lt;!--#set var="date" value="${DATE_LOCAL}_${DATE_GMT}" --&gt;
474 </pre>
475     <hr />
476
477     <h2><a id="conditionalexpressions"
478     name="conditionalexpressions">Conditional expressions</a></h2>
479
480     <p>Now that we have variables, and are able to set and compare
481     their values, we can use them to express conditionals. This
482     lets SSI be a tiny programming language of sorts.
483     <code>mod_include</code> provides an <code>if</code>,
484     <code>elif</code>, <code>else</code>, <code>endif</code>
485     structure for building conditional statements. This allows you
486     to effectively generate multiple logical pages out of one
487     actual page.</p>
488
489     <p>The structure of this conditional construct is:</p>
490 <pre>
491         &lt;!--#if expr="test_condition" --&gt;
492     &lt;!--#elif expr="test_condition" --&gt;
493     &lt;!--#else --&gt;
494     &lt;!--#endif --&gt;
495 </pre>
496
497     <p>A <em>test_condition</em> can be any sort of logical
498     comparison - either comparing values to one another, or testing
499     the ``truth'' of a particular value. (A given string is true if
500     it is nonempty.) For a full list of the comparison operators
501     available to you, see the <code>mod_include</code>
502     documentation. Here are some examples of how one might use this
503     construct.</p>
504
505     <p>In your configuration file, you could put the following
506     line:</p>
507 <pre>
508         BrowserMatchNoCase macintosh Mac
509         BrowserMatchNoCase MSIE InternetExplorer
510 </pre>
511
512     <p>This will set environment variables ``Mac'' and
513     ``InternetExplorer'' to true, if the client is running Internet
514     Explorer on a Macintosh.</p>
515
516     <p>Then, in your SSI-enabled document, you might do the
517     following:</p>
518 <pre>
519         &lt;!--#if expr="${Mac} &amp;&amp; ${InternetExplorer}" --&gt;
520         Apologetic text goes here
521         &lt;!--#else --&gt;
522         Cool JavaScript code goes here
523         &lt;!--#endif --&gt;
524 </pre>
525
526     <p>Not that I have anything against IE on Macs - I just
527     struggled for a few hours last week trying to get some
528     JavaScript working on IE on a Mac, when it was working
529     everywhere else. The above was the interim workaround.</p>
530
531     <p>Any other variable (either ones that you define, or normal
532     environment variables) can be used in conditional statements.
533     With Apache's ability to set environment variables with the
534     <code>SetEnvIf</code> directives, and other related directives,
535     this functionality can let you do some pretty involved dynamic
536     stuff without ever resorting to CGI.</p>
537     <hr />
538
539     <h2><a id="conclusion" name="conclusion">Conclusion</a></h2>
540
541     <p>SSI is certainly not a replacement for CGI, or other
542     technologies used for generating dynamic web pages. But it is a
543     great way to add small amounts of dynamic content to pages,
544     without doing a lot of extra work.</p>
545     <!--#include virtual="footer.html" -->
546   </body>
547 </html>
548