How this website is created ?

Before the creation of this current my blog “engine” was NanoBlogger. It is a very cool project which aims to construct a blog engine using only generic UNIX commands (cat, grep, sed, …).

After using it a while, I remarked that NanoBlogger generates its own text-based database to track modifications of articles. It also generates many files during the generation and creation process. This trough me away. Why not using the perfect tool to track dependencies and generate files ? GNU Make.

After some experiments, I choose Gnu Awk to parse content and tags, Markdown for translating a wiki-like syntax to html. And the last dependency is an ftp program and a shell script used to sync your local site to the web.

Templates

I use a template to generate xhtml structure. This template must contain tags in the form of :TAG_NAME: .

Why a so obvious tag ?

First we must have a symetric pre-suffix readable pattern : is a good choice.

Secondly we need a unique tag name pattern, a one who no man must write. The double collumns is not used in a pattern like that: :BLABLABLA:.

See the template for this site.

Awk script

To easily match a tag pattern, we use the pre-suffix as RS (Record Separator).

Now if we want to match :TAG:, we just have to write :

/^:TAG:$/ {
    Do what you want here...
}

Advanced constructs

To perform advanced construct in the awk script, we need to know the content file (paste the content at the :CONTENT: tag and the output file name to perform tree navigation.

To read the content file, we read the file in the :CONTENT: tag block.

/^:CONTENT:$/ {
    while ((getline content <input) > 0)
        print content >output;
    already_printed = "true";
}

To construct a navigation tree, your files must be organized in th same path. For this site, I have the “about”, “project”, … directories.

/^:HEADER:$/ {
    print "<a href=\"/davidcl/index.html\">davidcl</a> > " >output;
    num_directories = split (output, path, "/");
    for (i=1; i<num_directories; i++) {
        print "<a href=\"/davidcl/" path[i] "\">" path[i] "</a>" >output;
        print " > " >output;
    }

    name = path[num_directories];
    sub (/.html/, "", name);
    print name >output;

    already_printed = "true";
}

See the script for this site.

Makefile

The Makefile first define tools and root directories which will be parsed. If you want you can add per-directory rule and these rules will be included.

# Tools path
MARKDOWN = /usr/bin/markdown
AWK = /usr/bin/gawk
SH = /bin/sh
RM = /bin/rm -f
CAT = /bin/cat
TOUCH = /bin/touch

# Setting default searching directories
directories = projects articles about

# including per-directory specific rules (if any).
# Use to add sub-directories to the $(directories) variables
-include $(addsuffix /Makefile, $(directories))

# Adding others path to the directories variable after inclusion
directories += . styles

After this configuration definition we search for all .text (Markdown content) files, all .htm (xhtml content) files and all others files (images, css).

Then rules are defined. First, global commands :

Secondly, generic commands :

%.htm: %.text
    $(MARKDOWN) $< > $@

%.html: %.htm templates/default.template template.awk
    $(AWK) -f template.awk -v input="$<" -v output="$@" templates/default.template

%.atom: %.htm templates/atom-entry.template template.awk
    $(AWK) -f template.awk -v input="$<" -v output="$@" templates/atom-entry.template

See the makefile for this site.

Download

My website can be used as an example, simply delete the content and write your own.

Fork me on github !!!