this website

How I made this website

WDCMS: Willem's Disposable Content Management System


Years and years ago, the company where I was working: had a website. At that time there were no fancy and cheap content management systems for maintaining websites, and we really needed something for our computersystems and software. (SARA was and is running large computer systems for academic Netherland).

So I decided to create a simple content managment system and I choose m4 as the language. There is still something to be found on the web. It was really a very simple system, and I said from the beginning that this was a disposable content management system, to be thrown away as soon as the webmaster was able to use a real CMS: Dreamweaver, if I am correct.

And indeed, I removed wdcms completely, nowhere I could find a trace of it now.


As you can guess from the Drupal documentation on this website, I managed to create and maintain using Drupal, version 7. Now there is Drupal 8, and even Drupal 9. Drupal 7 was already somewhat bloated for 1300 files for the core, but Drupal 8 beats that easily: 24000 files for the core! Moreover, there is a tendency to use the command line to maintain and upgrade Drupal. That is understandable, and no problem for me, except that I do not have command line access to the system of my provider.

WDCMS born again

I decided to revive WDCMS as a tool to maintain a static, without PHP or SQL. First try was again with m4 as engine. Well, it turned out that at this time, m4 and me is not a good combination. M4 is very powerful, and has many serious uses, but for my project soon it became a nightmare. I was not able to write a single line of m4 code without debugging: adding or removing quotes until the desired effect was obtained. Needless to say: the code became quite unreadable. So, once more, I abandoned the project.

WDCMS born again born again

Next try was using Python as engine. This was from the beginning a success. Big difference between Python (or other similar languages: C++ or even Perl) and m4 is that with m4 the program is part of the content, while in Python the code is separated from the content: no hassle with quotes any more.

In short: there are the following important files:

  • wdcms.root: contains the location for the generated pages
  • template.html: a template from which the pages are build
  • 90-ratrabbit.css: the css to be used
  • 90-ratrabbit.js: the javascript to be used
  • the program that generates the website

All together less than 1000 lines ( version

And there is a directory structure, for example:

├── wdcms.root
├── template.html
├── ratrabbit.css
├── ratrabbit.js
├── menu.txt
├── content.txt
├── alracTTG/
│   ├── alracTTG.css
│   ├── downloads/
│   ├── run_alracTTG/
├── contact/
├── drupal/
│   ├── better_formats/

In each directory I can place

  • template.html: this one will replace template.html from parent directories. If template.html is absent, the file from the nearest parent is used. In the root, where we find wdcms.root, the file template.html is mandatory. Normally, you will have only one template.html.
  • menu.txt: define the main menu.
  • settings.txt: define some settings: parser, formatter, ...
  • content.txt: content of the page, written in markdown syntax If content.txt is absent, the content.txt from the nearest parent directory is used.
  • *.css *.js: one or more css and javascript files. References to these files, and files from parent directories are automatically included in the <head> part of the generated page.
  • trans.txt: a file with translations. Translations from parent directories are automatically handled as well.
  • head.html: The content of this file is placed in <head> of the generated page, together with the head.html's of parent directories.
  • wdcms.copy: a directory whose content will be copied to the destination. (NOT the directory wdcms.copy itself, but it's contents, for example .htaccess)

The program creates the website by visiting each directory in the source tree and perform the following actions:

  • create a directory with the same name in the destination tree.
  • copy *.css and *.js in it.
  • create 'index.html' using 'content.txt', .css, .js files, 'template.html', 'head.html' and '*.txt' from this directory and parents.

The context-sensitive links you see in the left region of the pages are automatically generated, so I have only to write the content.txt pages and, if I have some time to spare, add css and a translation to get a context-sensitive header.

All very simple! Of course, this system does not have nearly the power of a real CMS like Drupal or Wordpress. But, since the generated website is completely static, without any dependency of PHP or SQL, the website is not easy to hack.

For the ratrabbit website the time to generate the whole website is about 2 seconds when using "markdown" as filter for the "content.txt" files, about 2.7 seconds when using "pandoc" as filter (what I do).

Interested readers are welcome to the more in depth section.

WDCMS coded in rust: WDCMSR

Just as an exercise, I converted the Python version to the [rust programming language] (

I have to admit, that there are some strange constructs in the Python version, to which the rust compiler had insurmountable objections. After some fiddling: re-arrange the classes (or structs); playing with & and .clone(); etc. I managed to get a running rust version.

Other static website generators

When I finished WDCMS, I had a look at existing static website builders. There are quite a few! Many of them are listed here. Maybe I should have had a look at some of them before creating my own...