The Best Way to use SSI

This is what I consider to be the best approach to using Server Side Includes (SSI) on a web site. It applies equally well to the php include command and similar tools in other languages.

Introduction

Includes are a really useful way of storing repeated elements in a single place, considerably easing the process of maintaining a large site. For example, if you have a navigation menu that you use on every page:

<ul class="menu">
<li><a href="/">Home</a></li>
  <li><a href="about.htm">About</a></li>
  <li><a href="contact.htm">Contact</a></li>
</ul>

You could replace it with a single SSI call instead:

<!--#include virtual="/menu.txt" -->

Now, if you add a new element to the menu, you can do so by changing menu.txt instead of every page in the site.

That’s a big improvement, but it’s not getting the best out of SSI.

Problems

The problem with this functional approach to SSI, with each include file being self-contained and focussed on one thing, is that it typically leaves a lot of the page structure on the individual pages’ files. The menu example above might be employed like this:

<html>
<head>
  <title>My Great Company</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
  <div id="logo">GreatCo</div>
  <div id="menu"><!--#include virtual="/menu.txt" --></div>
  <div id="content">What a great company!</div>
</body>
</html>

Sure, you’ve moved the menu into a single file, but the code that controls where and how that menu appears is duplicated on every page. I know you can change a lot with just CSS, but often you need to add/remove/rearrange divs, and it’s even worse if you’re using table-based markup.

What you need to do is think about your individual pages’ markup in a different way.

A New Approach

All web pages (should) contain some content that’s unique to that particular page. Typically, there’s some markup that appears between the <body> tag and the beginning of the content on every page, there’s some more that appears between the end of it and the </body> tag. This markup will include site titles, menus, copyright notices, code for analytics and advertising and whatever else you need. The trick is to use single includes for the whole before and after code blocks. Consider this example:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>I Love Kittens: Home Page</title>
<meta name="author" content="Chris Hunt">
<link rel="stylesheet" type="text/css" href="kitties.css" />
</head>
<body>
<table>
<tr>
<td><h1>I Love Kittens</h1></td>
</tr>
<tr>
<td>
<h2>Home Page</h2>
<p>Aww... they're so cute!</p>
  </td>
</tr>
</table>
</body>
</html>

The code marked in red is the same on every page of the site, and could be moved across to includes. However, it can be useful for the individual pages to validate without the includes being, erm, included – so we’ll leave the main elements in place. Here’s the SSI version:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>I Love Kittens: Home Page</title>
<!--#include virtual="/head.txt" -->
</head>
<body>
<!--#include virtual="/top.txt" -->
<h2>Home Page</h2>
<p>Aww... they're so cute!</p>
<!--#include virtual="/bottom.txt" -->
</body>
</html>

The three included files, head.txt, top.txt and bottom.txt are, respectively:

<meta name="author" content="Chris Hunt">
<link rel="stylesheet" type="text/css" href="kitties.css">
<table>
<tr>
<td><h1>I Love Kittens</h1></td>
</tr>
<tr>
<td>
</td>
</tr>
</table>

Note that the three included files are not themselves complete HTML documents, or even well formed bits of XML – they’re just fragments of a page.

Now, suppose you decide to step into the 21st century and abandon tables-for-layout. It’s easy, you write your new CSS and change top.txt & bottom.txt:

<div id="banner">
<h1>I Love Stickers</h1>
</div>
<div id="content">
</div>

The new structure is instantly employed in every page of your site! Of course the same principle applies to less drastic changes (and to more complex designs!)

Going Further

You can make this approach even more powerful by using executable scripts in your cgi-bin instead of static include files. These scripts may just be a series of print statements, but potentially allow you to tweak the “constant” content of each page, for example highlighting the current page in a menu by checking the URL of the current page.

If you have islands of constant content in the middle of the unique stuff, feel free to add further includes to the mix, but follow the same principle – it’s just an arbitrary collection of tags that goes in a particular part of each page.

Conclusion

Although it flies in the face of normal computing best practice (where we try to encapsulate particular functions in particular files), this is what I’ve found to be the best strategy when using SSI. Try it on your site!

Leave a Comment