Posts tagged coleslaw

Blogging with Coleslaw

posted on 2013-10-14 10:34:44

Coleslaw is one of many static site generators and creates static HTML pages. It uses Common Lisp in the backend. In my case markdown is used as the post format. This post will cover issues I encountered during install and initial usage. My Server is running a headless CentOS 6 install.

As of October 2013 the SBCL version in the yum repo's is 1.0.38. When trying to run coleslaw a error occurs due to the cl-fad lib. Installing it via Quicklisp fails. As of SBCL 1.0.44 the missing functionality seems to be included: enhancement: new function: SB-EXT:DELETE-DIRECTORY is now provided.

I recall all this from memory. So I am not completely sure this was the line in question. Since latest version at the moment is 1.1.12, this does not matter much. Except for others encountering similar errors and finding this via google. :)

How to install the newest SBCL version and getting Quicklisp up and running, is already covered here.

Now first a description how my coleslaw setup works and what technologies are used, in case troubleshooting is needed later on. The blog runs on a hosted vserver, stored in a git repository served by gitolite (eventually gitlab will be put to use). Once changes are pushed into the git repo, via a post-receive hook the lisp code for converting the markdown posts is triggered. The .html files are copied to another folder which is served over an apache web server.

Posts have have the following structure, this is taken from this one here:

title: Blogging with Coleslaw
tags: coleslaw,sbcl,common lisp,lisp
date: 2013-10-14 10:34:44
format: md
Coleslaw is one of [many static site generators] ( and creates ...

For convenience reasons posts have filenames like:

Indicating content and having a prepended number for easier editing. The .post extension is needed. Posts are the only files that reside in the blogging repository that is checked out onto my client workstation. All conversion code is loaded via Quicklisp, no need to set anything up besides what will be covered here. To phrase it differently, in your blog repository NO additional directory structure is needed for post organization, NO additional code is needed. Things just work. I.e. this is what resides in my cloned repo called blog currently:

[sjas@lorelei ~/work/blog]% ls

It will not be disclosed how long just this took me to find out about the non-existant directory structure. :)

On the server the repository is stored as a bare repo, nothing to take care of since gitolite will handle this by itself. Only thing to fix is the post-receive hook. Hooks in git enable bash actions to be triggered upon repository interactions. bash code to happen prior or after pushes, commits, etc. is defined in hook files. These are placed in the .git folder of the repository where they should act. Here this means, the post-receive file has to be put into /var/lib/gitolite/repositories/blog.git/hooks on the server. If it were put within the client-side repo it will not work.

In my case this is the content of the file called post-receive:

########## CONFIGURATION VALUES ##########

# TMP_GIT_CLONE _must_ match one of the following in coleslawrc:
#   * The :repo argument (for a single-site setup) _or_
#   * An alist key (for a multi-site setup)

# Set LISP to your preferred implementation. The following
# implementations are currently supported:
#   * sbcl
#   * ccl


if cd `dirname "$0"`/..; then
cd $OLDPWD || exit 1
exit 1

git clone $GIT_REPO $TMP_GIT_CLONE || exit 1

if [ $LISP = sbcl ]; then
sbcl --eval "(ql:quickload 'coleslaw)" \
--eval "(coleslaw:main \"$TMP_GIT_CLONE\")" \
--eval "(coleslaw::exit)"
elif [ $LISP = ccl ]; then
echo "(ql:quickload 'coleslaw)(coleslaw:main \"$TMP_GIT_CLONE\")(coleslaw::exit)" | ccl -b
exit 1


TMP_GIT_CLONE must point to a temporal folder which is not used otherwise. This is not the folder where your repository resides, or where the html code will be pushed to. It is needed for generation purposes and will be deleted immediatly after posting.

Further on the server the .coleslawrc has to be placed in the home folder of the user being responsible for gitolite.

My .coleslawrc in /var/lib/gitolite on the server:

(:author "sjas"
 :deploy-dir "/var/www/html/sjas/blog/" ;; folder to be served
 :domain ""
 :feeds ("lisp")
 :plugins ((mathjax) (sitemap))
 :repo "/var/lib/gitolite/repositories/blog.git/tmp/" ;; tempfolder before stuff gets moved into DEPLOY, same as in post-receive
 :sitenav ((:url "" :name "Home") 
            (:url "" :name "Twitter") 
            (:url "" :name "Code"))
 :staging-dir "/tmp/coleslaw/"
 :title "A year and a smile."
 :theme "hyde")

Once all this is set, a virtual host entry in the apache config has to be created, maybe like this one here:



    DocumentRoot /var/www/html/sjas/blog/.curr/

    <Directory />
        Options FollowSymlinks
        Order allow,deny
        allow from all

    ErrorLog /var/log/blogsjas/error_log
    CustomLog /var/log/blogsjas/access common

    <IfModule mpm_itk_module>
        AssignUserId git git


Trick here is to set the DocumentRoot pointing to the symlink .curr which is created by coleslaw.

The mpm_itk_module is an apache extension to let a vhost run under a different user. Since I have the blog und git running under the same user, I do not have to watch out for file permission errors. Last thing to note here is, I forgot to create the ErrorLog and CustomLog files. Because of that nothing was served except the apache standard page, beside all else being set up properly. Once this was fixed, things looked like this on my workstation:

[sjas@lorelei ~/work/blog]% git add -A && git commit -m "update coleslaw" && git push
[master c9a5] update coleslaw
 3 files changed, 11 insertions(+), 2 deletions(-)
 delete mode 100644
 create mode 100644 .gitignore
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 688 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Initialized empty Git repository in /var/lib/gitolite/repositories/blog.git/tmp/.git/
remote: This is SBCL, an implementation of ANSI Common Lisp.
remote: More information about SBCL is available at <>.
remote: SBCL is free software, provided as is, with absolutely no warranty.
remote: It is mostly in the public domain; some portions are provided under
remote: BSD-style licenses.  See the CREDITS and COPYING files in the
remote: distribution for more information.
remote: To load "coleslaw":
remote:   Load 1 ASDF system:
remote:     coleslaw
remote: ; Loading "coleslaw"
remote: .......................
remote: ; compiling file "/var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/mathjax.lisp" (written 12 OCT 2013 12:59:42 AM):
remote: ; compiling (DEFPACKAGE :COLESLAW-MATHJAX ...)
remote: ; compiling (IN-PACKAGE :COLESLAW-MATHJAX)
remote: ; compiling (DEFVAR *MATHJAX-HEADER* ...)
remote: ; compiling (DEFUN ENABLE ...)
remote: ; /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/mathjax.fasl written
remote: ; compilation finished in 0:00:00.016
remote: ; compiling file "/var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/sitemap.lisp" (written 12 OCT 2013 12:59:42 AM):
remote: ; compiling (DEFPACKAGE :COLESLAW-SITEMAP ...)
remote: ; compiling (IN-PACKAGE :COLESLAW-SITEMAP)
remote: ; compiling (DEFMETHOD DEPLOY ...)
remote: ; compiling (DEFUN ENABLE ...)
remote: ; /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/sitemap.fasl written
remote: ; compilation finished in 0:00:00.006
remote: ; cp -R /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/themes/hyde/css .
remote: ; ln -sfn 1.html index.html
remote: ; mv /tmp/coleslaw/ /var/www/html/sjas/blog/generated/3590675951
remote: ; rm -r /var/www/html/sjas/blog/generated/3590675441/
remote: ; ln -sfn /var/www/html/sjas/blog/.curr /var/www/html/sjas/blog/.prev
remote: ; ln -sfn /var/www/html/sjas/blog/generated/3590675951 /var/www/html/sjas/blog/.curr
   e895..c9a5  master -> master
[sjas@lorelei ~/work/blog]%

And the then the software was up and running and the result is what you see here.

All this seems like an awful lot of work, but I wanted a fast, clean-looking, self-hosted blogging solution, working with git and being LISP-based for learning purposes. Other options would have been the clojure-based ones listed here and here.

This grew longer than anticipated, questions please via twitter until I get DISQUS up in here.

Hello World

posted on 2013-10-12 15:18:00

This is the first posting using a new static site generator based on Common Lisp. Setting this up could have been way easier with better documentation.

Next post will cover problems I encountered. For now back to real work.

This markdown cheat sheet might help me writing posts.

This blog covers .csv, .htaccess, .pfx, .vmx, /etc/crypttab, /etc/network/interfaces, /etc/sudoers, /proc, 10.04, 14.04, 16.04, AS, ASA, ControlPanel, DS1054Z, GPT, HWR, Hyper-V, IPSEC, KVM, LSI, LVM, LXC, MBR, MTU, MegaCli, PHP, PKI, PS1, R, RAID, S.M.A.R.T., SNMP, SSD, SSL, TLS, TRIM, VEEAM, VMware, VServer, VirtualBox, Virtuozzo, XenServer, acpi, adaptec, algorithm, ansible, apache, apache2.4, apachebench, apple, applet, arcconf, arch, architecture, areca, arping, asa, asdm, autoconf, awk, backup, bandit, bar, bash, benchmarking, binding, bitrate, blackarmor, blockdev, blowfish, bochs, bond, bonding, booknotes, bootable, bsd, btrfs, buffer, c-states, cache, caching, ccl, centos, certificate, certtool, cgdisk, cheatsheet, chrome, chroot, cisco, clamav, cli, clp, clush, cluster, cmd, coleslaw, colorscheme, common lisp, configuration management, console, container, containers, controller, cron, cryptsetup, csync2, cu, cups, cygwin, d-states, database, date, db2, dcfldd, dcim, dd, debian, debug, debugger, debugging, decimal, desktop, df, dhclient, dhcp, diff, dig, display manager, dm-crypt, dmesg, dmidecode, dns, docker, dos, drivers, dtrace, dtrace4linux, du, dynamictracing, e2fsck, eBPF, ebook, efi, egrep, emacs, encoding, env, error, ess, esx, esxcli, esxi, ethtool, evil, expect, exportfs, factory reset, factory_reset, factoryreset, fail2ban, fakeroot, fbsd, fdisk, fedora, file, files, filesystem, find, fio, firewall, firmware, fish, flashrom, forensics, free, freebsd, freedos, fritzbox, fsck, fstrim, ftp, ftps, g-states, gentoo, ghostscript, git, git-filter-branch, gitbucket, github, gitolite, global, gnutls, gradle, grep, grml, grub, grub2, guacamole, hardware, haskell, hdd, hdparm, hellowor, hex, hexdump, history, howto, htop, htpasswd, http, httpd, https, i3, icmp, ifenslave, iftop, iis, imagemagick, imap, imaps, init, innoDB, innodb, inodes, intel, ioncube, ios, iostat, ip, iperf, iphone, ipmi, ipmitool, iproute2, ipsec, iptables, ipv6, irc, irssi, iw, iwconfig, iwlist, iwlwifi, jailbreak, jails, java, javascript, javaws, js, juniper, junit, kali, kde, kemp, kernel, keyremap, kill, kpartx, krypton, lacp, lamp, languages, ldap, ldapsearch, less, leviathan, liero, lightning, links, linux, linuxin3months, lisp, list, livedisk, lmctfy, loadbalancing, locale, log, logrotate, looback, loopback, losetup, lsblk, lsi, lsof, lsusb, lsyncd, luks, lvextend, lvm, lvm2, lvreduce, lxc, lxde, macbook, macro, magento, mailclient, mailing, mailq, make-jpkg, manpages, markdown, mbr, mdadm, megacli, micro sd, microsoft, minicom, mkfs, mktemp, mod_pagespeed, mod_proxy, modbus, modprobe, mount, mouse, movement, mpstat, multitasking, myISAM, mysql, mysql 5.7, mysql workbench, mysqlcheck, mysqldump, nagios, nas, nat, nc, netfilter, networking, nfs, nginx, nmap, nocaps, nodejs, numberingsystem, numbers, od, onyx, opcode-cache, openVZ, openlierox, openssl, openvpn, openvswitch, openwrt, oracle linux, org-mode, os, oscilloscope, overview, parallel, parameter expansion, parted, partitioning, passwd, patch, pct, pdf, performance, pfsense, php, php7, phpmyadmin, pi, pidgin, pidstat, pins, pkill, plasma, plesk, plugin, posix, postfix, postfixadmin, postgres, postgresql, poudriere, powershell, preview, profiling, prompt, proxmox, ps, puppet, pv, pveam, pvecm, pvesm, pvresize, python, python3, qemu, qemu-img, qm, qmrestore, quicklisp, quickshare, r, racktables, raid, raspberry pi, raspberrypi, raspbian, rbpi, rdp, redhat, redirect, registry, requirements, resize2fs, rewrite, rewrites, rhel, rigol, roccat, routing, rs0485, rs232, rsync, s-states, s_client, samba, sar, sata, sbcl, scite, scp, screen, scripting, seafile, seagate, security, sed, serial, serial port, setup, sftp, sg300, shell, shopware, shortcuts, showmount, signals, slattach, slip, slow-query-log, smbclient, snmpget, snmpwalk, software RAID, software raid, softwareraid, sophos, spacemacs, spam, specification, speedport, spi, sqlite, squid, ssd, ssh, ssh-add, sshd, ssl, stats, storage, strace, stronswan, su, submodules, subzone, sudo, sudoers, sup, swaks, swap, switch, switching, synaptics, synergy, sysfs, systemd, systemtap, tar, tcpdump, tcsh, tee, telnet, terminal, terminator, testdisk, testing, throughput, tmux, todo, tomcat, top, tput, trafficshaping, ttl, tuning, tunnel, tunneling, typo3, uboot, ubuntu, ubuntu 16.04, ubuntu16.04, udev, uefi, ulimit, uname, unetbootin, unit testing, upstart, uptime, usb, usbstick, utf8, utm, utm 220, ux305, vcs, vgchange, vim, vimdiff, virtualbox, virtualization, visual studio code, vlan, vmstat, vmware, vnc, vncviewer, voltage, vpn, vsphere, vzdump, w, w701, wakeonlan, wargames, web, webdav, weechat, wget, whois, wicd, wifi, windowmanager, windows, wine, wireshark, wpa, wpa_passphrase, wpa_supplicant, x11vnc, x2x, xfce, xfreerdp, xmodem, xterm, xxd, yum, zones, zsh

Unless otherwise credited all material Creative Commons License by sjas