In our last exciting episode, I promised a crude flowchart and I don't want to let anyone down. You'll need to click on it to see the whole thing. Feel free to open it in another window and follow along.

As I read my previous posts it occurred to me that you may not see where I am leading with all these files. The idea I have in mind is to allow editing a particular section of the web site in just one file, but more importantly, I want to limit the changes made to that file to affect only that portion of the web site we are making changes to. As long as each section edit maintains well formed markup, that should happen in each instance.

The problem with poorly formed markup is that a tag opened in one section and not properly closed might present problems in sections later down the line. Well formed markup requires that all opened tags are closed except for singular instance tags (like img tags) which do not open and close.

So, the reason why we split each page into many files is to make updates easier to perform. If I need to make changes to the left hand navigation across the whole web site, I only need to make changes to one file (e.g. left_menu.html) and any changes that I make there will not accidentally change the site header or the content.

When I designed the site above, I needed to allow the site owner's office staff to update the left and right content columns. I feared that giving them access to a whole page might end in disaster, so I originally gave them FTP access1 to only those two files. Now, I didn't fear that, "I just wiped out the whole web site. You can recover it, right?" phone call. I'm sure that has never happened to anyone.

I also like to have separate files for each section because I have been known to accidental open a file instead of saving it. Basically reverting any changes since the last save. On a large site with a lot of changes I have been known to wipe out hours of work from this one mistake.

Let's take a closer look at the index file. When I mention an index file, I mean any file which is requested by the web browser. Perhaps I should have called them requested files, but the damage is done now, and I call them index files when I refer to them in my own head.

The index file controls the customized sections of the page. Let's say that we promised a vendor a skyscraper ad in the right-most column of most pages on a web site with 3 or 4 columns. On some pages there will only be 3 columns and no skyscraper advertisement. On all other pages there will be 4 columns. The 3 regular columns and a fourth column with a large animated skyscraper advertisement. (I'd like to remind everyone that in production, the file name is not located in an html comment in the file. I placed it here to aid readers.) I didn't fully test this last example. If you find a problem, let me know.

HTML:
  1. <!-- /events.html -->
  2. <!--#set var="title" value="Events by Events-R-Us" -->
  3.  
  4. <!--#set var="content_right" value="/site/content/events_right.html" -->
  5. <!--#set var="content_left"  value="/site/content/events_left.html" -->
  6.  
  7. <!--#set var="right_column" value="yes" -->
  8.  
  9. <!--#include virtual="/site/default_values.shtml" -->

HTML:
  1. <!-- /site/default_values.shtml -->
  2.  
  3. <!--#if expr="! $title" -->
  4.     <!--#set var="title" value="Events-R-Us" -->
  5. <!--#endif -->
  6.  
  7. <!--#if expr="! $keywords" -->
  8.     <!--#set var="keywords" value="a list of, relevent, keywords" -->
  9. <!--#endif -->
  10.  
  11. <!--#if expr="! $description" -->
  12.     <!--#set var="keywords" value="A descriptio of this page." -->
  13. <!--#endif -->
  14.  
  15. <!--#if expr="! $content_right" -->
  16.     <!--#set var="content_right" value="/site/content/content_right.html" -->
  17. <!--#endif -->
  18.  
  19. <!--#if expr="! $content_left" -->
  20.     <!--#set var="content_left" value="/site/content/content_left.html" -->
  21. <!--#endif -->
  22.  
  23. <!--#if expr="$right_column != 'yes'" -->
  24.     <!--#set var="$right_column" value="no" -->
  25. <!--#endif -->
  26.  
  27. <!--#include virtual="/site/load_page.shtml" -->

HTML:
  1. <!-- /site/load_page.shtml -->
  2.  
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.dfwrein.com/html4-embed.dtd">
  4.     <title><!--#echo var="title" --></title>
  5.     <meta http-equiv="Content-Type" content="text-html; charset=utf-8">
  6.     <meta http-equiv="Content-language" content="en-US">
  7.     <meta http-equiv="pragma" content="no-cache">
  8.     <meta http-equiv="cache-control" content="no-cache">
  9.  
  10.  
  11.     <meta name="keywords" content="$keywords">
  12.     <meta name="description" content="$description">
  13.     <meta name="robots" content="index,follow">
  14.     <meta name="revisit-after" content="7 days">
  15.     <meta name="email" content="[email protected]">
  16.  
  17.     <link rel="stylesheet" type="text/css" href="/general.css">
  18. </head>
  19.     <div id="left-menu"><!--#include virtual="/site/include/left_menu.html" --></div>
  20.     <div id="content-right"><!--#include virtual="$content_right" --></div>
  21.     <div id="content-left"><!--#include virtual="$content_left" --></div>
  22.     <!--#if expr="$right_column = 'yes'" -->
  23.         <div id="coulmn-right"><!--#set var="skyscraper" value="/site/ads/skyscaper.html" --></div>
  24.     <!--#endif -->
  25. </body>
  26. </html>
  27. <p>In the default values file, the ! means not, just as it does in many programming languages. So ! $title evaluates to true if there has been no set statement for title. Apache let's us refer to a variable by using a $ prefix to the value inside quotes. Outside quotes, we should use the echo directive.</p>
  28. <p>I added the $right_column check in the default values file for a sanity check. When I use it in subsequent files I want to know that it will always be either "yes" or "no". Nothing in between. I would suggest doing this with any variable which is going to hold some kind of defined state. Like an option list (e.g. months of the year, days of the week, etc.) or a Boolean value (e.g. yes/no, true/false, etc.). In the example above we defaulted to "no." Below we default to "yes."</p>
  29. [html]
  30. <!--#if expr="$right_column != 'no'" -->
  31.     <!--#set var="$right_column" value="yes" -->
  32. <!--#endif -->

I placed the skyscraper conditional in the page loading file because I didn't want the div to be there on pages that don't include it.

In practice, I don't use so many lines in each file. The conditionals are usually all on one line. Apache leaves a blank line for each line I use and that means the top of the file has a lot of blank lines on it. I don't care for that. Once I set up a few of these very simple file systems and create a project on my editor, it was easy to set this same thing up on other web sites.

You can view the SSI directives in more detail at the Apache Docs. My virtual host uses the latest Apache version (2.2 at this writing). If yours doesn't, drop me a line and I'll set you up with mine.

That ends this series. Feel free to ask questions and mingle.

Happy Programming

Foot notes: 1. Later, I designed a form to allow them to access those files through a web page.

Digg!