Contemplating “the Digg effect” last week, I started experimenting with fast and efficient ways of displaying dynamic content. This method, although overkill, looked promising; A basic CMS written entirely in Apache config rules.

If you’re short on time, and just want to see it working, you can view the demo and download the source files. Don’t forget to read the installation instructions.

Otherwise read on - we will make our own Apache CMS from scratch.


STEP 1 - Serving Files
 

Let’s start easy. Apache is designed (obviously) to serve any type of file to a client who requests them. It is fast and efficient, using only the basic features of the web server. I begin by uploading several files to my web root - these could be Word files, images, whatever I like.


STEP 2 - Directory Listings

Depending on my Apache configuration, when I visit my I will either see an error message (because no default web page is available), or a directory listing. We want the directory listing. To make sure it shows, we have our first configuration line:

Options +Indexes

Admittedly the directory listing isn’t pretty, but we can work on presentation soon. First we need to generate the correct HTML for the data we want to display.


STEP 3 - Configuring Directory Listings

First let’s enable fancy indexing, and ensure it outputs compliant XHTML.

IndexOptions +FancyIndexingIndexOptions +XHTML

Because we’re going to be adding our own headers and footers to the directory listing, we need to disable unwanted Apache output.

IndexOptions +SuppressHTMLPreamble

Now let’s choose what information is displayed. This is down to personal preference, and the types of files that will be served by your CMS. In my case I only want a list of files, with nice icons, and a description for each entry. So I suppress information I don’t want to see, and add additional information;

IndexOptions +SuppressLastModifiedIndexOptions +SuppressSizeIndexOptions +ScanHTMLTitles

Finally I add a little bit of formatting to the data before we start styling;

IndexOptions +DescriptionWidth=60IndexOptions +NameWidth=50

Try refreshing your directory listing. Looks pretty different already, doesn’t it?


STEP 4 - Headers and Footers

Now we need to add HTML headers and footers to the directory listing. The header can include a site logo and some introductory text, and a copyright notice or similar in the footer. We can also use the HTML header to include CSS for styling our page.  I keep the headers and footers in the directory that they relate to - that way I can have different introductory text for subdirectories off the homepage. First set the headers and footers in our .htaccess file:

HeaderName header.html
ReadmeName footer.html

Then we write our header.html file:

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

<html>
 <head>
  <title>Apache Demonstration</title>

 </head>
 <body>

  <h1>Welcome to my Apache Demonstration</h1>

And finally our footer.html file:

</body>
</html>

Now when you refresh your directory listing, it should look a bit more like a web page. Note the directory listing includes our new files - we don’t want to show them to visitors as they are irrelevant to our actual content. So we add an extra directive in .htaccess:

IndexIgnore header.html footer.html


STEP 5 - Adding Other Items

I also wanted to add images, external style sheets to my headers and footers, which shouldn’t be displayed to visitors. I created an ‘etc’ directory off the web root and hid it in my .htaccess:

IndexIgnore etc

Now I can upload logos, CSS files (covered next), file type icons (covered next) and anything else for the presentation of the directory listings. Try adding your logo to the header.  STEP 6 - USING CSS FOR PRESENTATION CSS is powerful enough to control Apache’s valid XHTML output of directory listings. Design your own stylesheet to match your site or corporate brand. You can use mine as a template:

<style type=”text/css”>
body, pre {
 font-family: “Lucida Grande”, “Lucida Sans”, “Lucida Sans Unicode”, “Lucida”, Verdana, “Bitstream Vera Sans”, sans-serif;
}

body {
 font-size: 0.85em;
 margin-left: 25%;
 margin-right: 25%;
 color: #333;
}

h1 {
 font-family: palatino linotype, book antiqua, palatino, serif;
 font-size: 1.7em;
 border-bottom: #333 1px solid;
 margin-top: 30px;
}

p {
 line-height: 1.6em;
 text-align: justify;
}

a {
 color: #004eff;
}

a:visited {
 color: #4800ff;
}

hr {
 border: 0;
 border-bottom: 1px #999 solid;
 height: 1px;
}

pre {
 margin: 40px 0;
 font-size: 1em;
 line-height: 2em;
}

</style>


STEP 7 - File Type Icons

The default icons supplied with Apache can look a bit dreary compared to more modern icons available. I have modified some of Famfamfam’s icons for directory listings, and written some directives for .htaccess to read the new icons. Icons are kept in ‘etc/icons’ - see our previous post for free icons if you don’t have any.

AddIconByEncoding (CMP,/etc/icons/compressed.png) x-compress x-gzip
AddIconByType (TXT,/etc/icons/text.png) text/*
AddIconByType (TXT,/etc/icons/text.png) .txt
AddIconByType (IMG,/etc/icons/image.png) image/*
AddIconByType (SND,/etc/icons/sound.png) audio/*
AddIconByType (VID,/etc/icons/movie.png) video/*

AddIcon /etc/icons/compressed.png .tar
AddIcon /etc/icons/back.png ..
AddIcon /etc/icons/readme.png README
AddIcon /etc/icons/folder.png ^^DIRECTORY^^


Complete

And there we have it - a simple content management system using only Apache .htaccess directives. Anyone with access can upload Word documents, photos, MP3s or movies without any knowledge of HTML or CSS. The system is lean and mean, generating pages in a fraction of a second (especially compared with the huge CMSs available).  It’s perfect for intranets when you only have 20 minutes to make one. Or maybe a geek/hacker/personal web site. I haven’t made a satisfactory client/corporate implementation, and I don’t think I will in the near future. Clients just aren’t any fun.

You can take this further by using CGI, PHP or whatever scripts to add more functionality to pages. Using a simple Perl script in place of the ‘header.html’ file, you could dynamically generate introductory text based on a database, readme file, or anything else you wanted. Or use server-side includes for the header, with just the introductory text changing (highly recommended).


Demo & Download

You can try the live demo here, and download an archive of my complete setup here. Look at our previous post for icon ideas. Please don’t forget to link to Famfamfam if you use the icons supplied with the demo.

What would you use it for? How would you improve it?