Before I built this site I came up with three key requirements:
- Must be really easy to add new content.
- Must not be bloated with blog/CMS software.
- Must not use a database backend.
Number 1 is pretty obvious, number 2 was because I wanted to keep the site as lightweight as possible and number 3 was to help save hosting costs. (MS SQL Server databases usually incur an extra charge, and I didn't want to use MySQL).
The backend for the site was written in C#, as an ASP.NET Webforms application. I may well rewrite it as an ASP.NET MVC application – if I ever get the time!
The only element of the site that is managed by the CMS is the collection of articles.
Each article consists of at least 2 files. The files are stored in a single folder within the website.
The first file is a "meta data" file and the second is a "body content" file. They are named using this pattern (where xxx is a number):
Here's the contents of the meta data file for this article (at the time of writing):
<?xml version="1.0" encoding="utf-8" ?>
<article title="How this site works / building a rudimentary flat-file CMS" created="2010-02-28">
<summary>A description of how this site works, including details of the rudimentary flat file CMS it uses.</summary>
As you can see, the meta data file provides the title, summary and creation date for the article.
The body content file contains plain text that has been marked up with MarkDown.
In addition, an optional "head content" file can be added using this pattern:
Loading articles into memory
When the site is first accessed a static singleton class called
ArticleManager is constructed.
ArticleManager scans the articles folder and reads each meta data file.
The meta data information is stored in a series of
Article objects that are held within the
ArticleManager. These objects are kept until the application is recycled. One additional piece of meta information that isn't taken from the meta data file is the "Last modified" date. This date is deduced by looking at the last modified date for the body content file.
When a particular article is viewed the appropriate
Article object is retrieved from the
ArticleManager and a method called
GetArticleContent() is called on the
GetArticleContent() returns an
ArticleContent object, either by creating a new one (and then caching it) or by looking in the Cache to see if it already exists.
Creating the ArticleContent object
ArticleContent object holds the head and body content along with a list of section names.
When a new
ArticleContent object is constructed the following steps take place:
- Body content file is read from the disk and all of the H3 headings are recorded as section names.
- Body content is run through the Markdown transform.
- H3 tags have section ids inserted into them (to allow in-page linking).
- Optional head content file is loaded (if present).
Rendering an article
Every article is viewed in the
ArticleView.aspx page. I use URL rewriting (provided by my web host) to mask the page name. (That's why you can't see it in the URL at the moment).
ArticleContent has been retrieved it's just a matter of writing the different pieces of content into a series of Literal/Repeater controls.
Adding new content
This is how I add a new article to the site:
- Create a new body content and meta data file.
- Write my article in the body content file.
- Upload the 2 files to the articles folder.
- Use an administration page to empty the Cache and recycle the meta data cache within
I use the following tools and jQuery plugins to give the page some visual flair: