Designing an Offline CMS

michaelmior profile image Michael Mior Originally published at michael.mior.ca on ・3 min read

First the obvious question. What on earth is an offline CMS? Isn’t the whole point of having a CMS that you don’t have to change anything offline? Well, yes that’s true. But recently I ran into a problem.

When I started my Masters degree, the department wanted me to create a webpage, but all I could really do was serve boring old static content. Well, that’s not entirely true, since there was an offer to set up a reverse proxy with my own LAMP stack, but that seemed like overkill for my humble little homepage. I also knew that I sure didn’t want to have to edit pages one by one every time I wanted to change common content. I also didn’t want to have to upload things manually every time things changed.

I did some searching around, and I decided to start with the Cheetah template engine. It’s got basically all the template goodness you need and a nice, clean syntax. So I created some Cheetah templates, and wrote a little script to generate all my files, and everything worked just fine. But I didn’t want to stop there. So I decided to throw in some of the goodness of SASS. (If you’re not familiar with SASS, check out the link, it’ll change your life.) Finally, just for good measure, I decided to throw in cssoptimizer and jsmin to pack everything down to size.

Finally, just to satisfy my aching fingers, I decided to write a Makefile that would perform the whole shebang: generate the static HTML, optimize JS and CSS code, and upload any changes to the server.

SERVER = yourserverhere

JS = $(wildcard src/js/*.js)
JS_OPT = $(patsubst src/js/%.js,web/js/%.js, $(JS))

SASS = $(wildcard src/sass/*.sass)
CSS = $(patsubst src/sass/%.sass,web/css/%.css, $(SASS))

TMPL = $(wildcard src/tmpl/*.tmpl)
TMPL_INC = $(wildcard src/tmpl/inc/*.tmpl)
HTM = $(patsubst src/tmpl/%.tmpl,web/%.htm, $(TMPL))

# Build all JavaScript, CSS, and XHTML files
all: $(JS_OPT) $(CSS) $(HTM)

# Remove all built files from the output directory
 rm -f web/*.htm
 rm -f web/js/*.js rm -f web/css/*.css

# Upload the final site to the server
put: all
 rsync -avr --delete web/ $(SERVER):~/public_html

# Optimize JavaScript files
$(JS_OPT): web/js/%.js: src/js/%.js
 cat $< | ./bin/jsmin > $@

# Optimize CSS files
$(CSS): web/css/%.css: src/sass/%.sass
 sass $< | ./bin/cssoptimizer -i $@

# Ensure XHTML is rebuilt when included templates change

$(HTM): web/%.htm: src/tmpl/%.tmpl
 (cd src/tmpl; cheetah fill --nobackup --oext=$(suffix $@) --odir=../../$(dir $@) $(notdir $<))

To get this to work for you, you should just be able to change SERVER to the address of your web server. The directory structure I used looks like this:

  • bin
  • src
    • tmpl
    • inc
    • sass
    • js
  • web
    • img <!--lint enable list-item-spacing no-missing-blank-lines-->

Finally, here’s a complete list of download locations for all the tools I used:

I found out when researching for this post that Lakshmi Vyas has already come up with a solution called Hyde for Python. There is also jekyll which uses Ruby. This just gives you more approaches to building a custom tool that suits your needs.

If you have any tips for generating static web content, post in the comments!


Editor guide