WofFS' Content Machine
2e3c418e — Frank Doepper a month ago
GitHub -> sourcehut
5f53ad2e — Frank Doepper 6 years ago
IfModule mod_rewrite.c
4daf8435 — Frank Doepper 6 years ago
use Text::Markdown::Discount if possible



You can also use your local clone with git send-email.

#WofFS' Content Machine

CMS verpiss dich, keiner vermisst dich!

WofFS' Content Machine is a tiny perl CGI which takes a directory tree of Markdown files or shell scripts (or whatever) and turns it into a browsable website.


  • Pages are (optionally) written in Markdown.
  • One page — one file.
  • Page titles and menu entries are taken from the file names.
  • The menu tree is built from the directory structure. Choose how many levels are uncollapsed by default.
  • It is very extensible: use shell or perl scripts for simplest creation of dynamic pages or to introduce other source formats than Markdown.
  • Builtin smart redirection in case of moved pages.
  • No configuration needed! Plug and play! The CGI tries hard to find the URL of itself automatically.
  • You can have hidden pages (which do not appear in the menu).
  • Redirects can be created by placing symlinks.
  • It supports Apache or lighttpd mod_rewrite for friendly URLs.
  • It is secure by design: only the configured directory is scanned for source files. Nothing else. The request URL is not getting converted into some file path. This takes away many opportunities for exploits. Note: shell, perl or php files in the source tree get executed. You have been warned. .-)
  • There is no need for write permission for the script on the web server.
  • It is very small and fast. Any file which must be opened gets read only once. Only information that is really needed for computing the result is taken from the filesystem. There is no DB connection.
  • It is tested under Debian and Ubuntu with Apache, thttpd and lighttpd. It should work with any Linux distributon and other unix-like systems. Anyone want to try Windows or Mac?

#What it is not

  • There is no embedded editor. (Well, you could install one.) Just upload your files.
  • There are not many variables. Only content, navigation, page title and URL prefix are substituted in the HTML template.
  • There is no HTTP header management, no cookies. Only Last-Modified is set.


  • Setup your web server (apache or lighttpd are recommended), and install perl and markdown, too. On a Debian system:

    apt-get install apache2 perl markdown

  • Download wcm and unpack it in your document root (or whereever you want):

    cd /var/www wget http://woffs.de/downloads/wcm-20120410.tar.gz tar xvzf wcm-20120410.tar.gz

  • Point your browser at http://localhost/wcm-20120410/index.pl. If you just see the source code of the perl script, you have to include something like

    <Directory /var/www/wcm-20120410/> AllowOverride All

    in your /etc/apache2/sites-available/default or whereever your apache config is. Reload config:

    /etc/init.d/apache2 reload

  • Now your browser should display the WCM page. Please drop me a line if this is not the case, so I can update the HOWTO accordingly.

  • If rewriting works, you can try http://localhost/wcm-20120410/, and the links will be nicer ("/WCM" instead of "/index.pl?page=WCM").

  • Look at the files under /var/www/wcm-20120410/src/, menu and content come from there.

  • File extensions are

    • sh: shell script (gets executed!) with Markdown output
    • bash: bash script (gets executed!) with Markdown output
    • php: php script (gets executed!) with raw HTML output
    • mphp: php script (gets executed!) with Markdown output
    • pl: perl script (gets executed!) with taint checks enabled, with Markdown output
    • cgi: executable (gets executed!) with Markdown output
    • html: raw HTML text
    • any other extension (or no extension): Markdown text
  • Everything before the first "_" in the filename is ignored. You can use that for menu sorting. If the Filename begins with "0", the File does not show up in the menu (a hidden entry).

  • You can have subdirectories for submenus. Edit the $menulevel value in index.pl to decide how many levels of submenus are shown for not-selected items. (The submenu of the selected item will always be shown.)

  • You can use the special filename "index" (or better "0_index" or "00_index", or "00_index.sh" if it is a shell script, etc) to have a directory index.

  • Within the text and the html template you can use special strings:

    • __prefix__ will be replaced by the starting part of the URL leading to the doc root (http://woffs.de/ in this case)
    • __pprefix__ will be replaced by the starting part of the URL leading to the page (http://woffs.de/ in this case)
  • Only within the html template you can additionally use:

    • __navi__ will be replaced by the menu (constructed by "src" directory tree)
    • __title__ will be replaced by the page title (derived from file name)
    • __content__ will be replaced by the page content (file content or script output)
  • You can (ab)use symlinks to point to another page. A redirection will then be created.


You are invited to have a look at the source code of the main script and to download wcm-20120410.tar.gz including some examples for easy setup.

The Software is Licensed under GNU AGPL.

You can browse the Git repository or get your copy with

git clone git://woffs.de/git/fd/wcm.git

or use sourcehut.

Feel free to contact me.


After discovering that I don't need embedded HTML editors, although I want to enter the content in a readable and writable way; and that I don't need a CMS, although I want automatic menus, I decided to write my own Content Machine.

One weekend in late August 2010 I spent some hours with this, and finally it ended up in ~130 lines of a perl CGI which serves the whole thing. All in one script!

With a little bit of shell magic and pandoc I moved my own Webpage from LightNEasy (which is a really light CMS, but still much more than I need) to my new Content Machine within some hours.

#Similar projects by others'

  • werc is "a minimalist web anti-framework"
  • Commonplace is "a wiki-like way to store and browse Markdown writings"