2026-01-25
Abandoning complexity
I have again re-configured and re-designed my blog. I haven’t been writing much the last years (decade?!) partially because my previous setup was just tedious to work with. I had over the years created all sorts of scripts and plugins, and other mixins, in total some 1000s lines of code, and frankly kept forgetting what most of it actually did.
I had at some point moved away from Jekyll and instead was using the Pelican site generator. My reason was that I had grown an aversion for Ruby and didn’t want to maintain all that code that I had written for Jekyll any more. So I refactored it into Python, and used it in Pelican instead.
This certainly streamlined my site generation process and unified some of the scripts into more modular code, but again after a time I couldn’t remember what much of it did (or why).
Eventually I realised that the complexities of maintaining the code, and the processes to applying it to my content, with also changing underlying infrastructure, was just not tenable. I just wasn’t following up on publishing, even though I wrote a lot of drafts for new blog posts.
In an attempt to complete these and not get distracted by the surrounding framework, I have abandoned it all. I now just pipe my Markdown into Pandoc, relying on a basic CSS structure (courtesy of Simple.css), and don’t think about it any more.
Integration into Gitolite
I use gitolite to host my personal repos and recently learned that gitolite supports local hooks. I was curious to know if these could be used to generate the site when I came across a blog post from Martine Lenders about doing just that, but for her Pelicon-based blog. Have a look at her post for full details. Additionally, I found a Github repo from the Oregon State Universities Open Source Lab which provides a basic “hooks framework” appropriate for gitolite. I taken both of these and remixed my own solution that
- is modular and lets me set which hook to apply for which repo,
- supports reading config from the gitolite repos
(e.g.
git config ...), - and is reasonably simple to use and maintain (ideally its a setup once sort of deal)
The first set is to activate local hooks in gitolite
(I’m using version 3.6.14), by updating the RC file with
(located at
/var/lib/gitolite/.gitolite.rc):
LOCAL_CODE => "$ENV{HOME}/local",and then creating the needed directory structure for the hooks:
# login or sudo -s at the gitolite user
mkdir -p <gitolite home>/local/hooks/{common,custom}We then add our dispatch hook to
local/hooks/common/post-receive with the
following content:
#!/bin/sh
# inspired by https://github.com/osuosl/gitolite-hooks
enabled_hooks="$(git config hooks.enabled)"
hooks_path="${HOME}/local/hooks/custom/"
if [ -n "${enabled_hooks}" ] ; then
read input
# change separator to comma
OLDIFS="$IFS"
IFS=","
for i in $enabled_hooks ; do
# reset IFS
IFS=$OLDIFS
# remove extra whitespace
hook="${hooks_path}${i//[[:space:]]}"
if [ -f ${hook} ] ; then
echo "executing ${hook}"
echo $input | . ${hook}
else
echo "warning: ${hook} not found"
fi
done
fiand then in the local/hooks/custom
directory we add the generate-blog hook
with content:
#!/bin/sh
# Set created files to be readable only for user and group
umask 0022
# Get pelican configuration of repository
TARGET_DIR="$(git config --get custom.targetdir)"
# check for required settings, if not finish silently
[ -n "${TARGET_DIR}" ] || exit 0
# create temporary directory
TMP_DIR="$(mktemp -d)"
trap 'rm -rf -- "${TMP_DIR}"' EXIT
# Copy repository including submodules into temporary directory
git clone --recursive --depth=1 file://${PWD} "${TMP_DIR}"
# If copying repository was successful
if [ $? -eq 0 ]; then
# Generate output files to target directory
echo "Generating blog"
make -C "${TMP_DIR}" && \
rm -rf "${TARGET_DIR}"/* && \
cp -r "${TMP_DIR}"/build/* "${TARGET_DIR}"
fiImportant ensure that both hooks have the execution bit set!
If you want, at this point you can call
gitolite setup (as the gitolite user) to
propagate the hooks across all the repos, but this will
happen automatically for new repos as well.
Finally we update our blog entry in the
gitolite.conf file (within the gitolite
admin repo) with:
config hooks.enabled = generate-blog
config custom.targetdir = <path to httpd site directory>We can then commit and push this. And assuming that also our dependencies are installed, we should on each push to the repo now automatically re-generate the blog.
Future Ideas
Design and typography are some things that have interested me for a while and I always want to my content (whether informal blogs or formal writing) to reflect this to some extent. The new blog layout does nothing ground breaking, and as I mentioned above, I don’t want to get bogged down with extra work. That being said, I do find it wonderful, that even in the domain of Pandoc templating, there are attempts to bring this to a typographic ideal. For instance in the case of the Tufte Pandoc CSS theme project, which implements the design ethos of Edward Tufte, see the post by Dave Liepmann for details. Another inspiration is the Pandoc Markdown CSS theme by Jake Zimmerman, which provides a design that closely matches the native Markdown schema. Perhaps in the not so distant future I will attempt to incorporate some of the design elements into my own blog.