A while ago I switched my blog from WordPress to Jekyll and github pages - partly because its better for code, and partly because I wanted one less system to deal with.

For the most part I am pretty happy with it, but there are a few things that aren’t as easy as they could be, mostly because it is a very flexible system and there is no standard way to do things.

I tend to work on more than one post at a time and publish them in no particular order, which means that keeping everything in the main branch and pushing when everything is done locally won’t work very well. I also want to use multiple devices, which means that there will be unfinished posts in the github repo.

Being based on git, version control in general is not a problem. If anything, there is too much control. I went through quite a few approaches before finding something that really works.

Git Versioning

My initial approach was to use git branches - create the post on a new branch and merge it into master when done.

That works, but is a bit more complex than necessary - keeping track of the unpublished posts can be tricky, and you can’t easily have more than one open at the same time.

Jekyll Post “published” Setting

If you add

published:false

in the yaml header of your post, it will not appear in views. Unfortunately there is no easy way to override this locally, which makes local preview difficult.

Ignored Folder

One approach I tried is to have Jekyll ignore drafts. By default, jekyll will ignore anything starting with an underscore - anything under _posts/_drafts won’t be processed.

To get a local preview, temporarily rename the folder to _posts/drafts, and your local jekyll instance will show the draft posts.

While this is similar to modifying the published setting in individual posts, it has the advantage that you can prevent accidental publishing of draft posts by adding _posts/drafts to .gitignore

Modified Views

Another option would be to edit the views to check site.showDrafts and page.status, but I decided against that in the interests of keeping the solution generic - it is better if it is possible to use standard templates, especially given that I am working on an editor app which should be able to work on any Jekyll blog.

Future dated posts

While a “show unpublished” setting seems like something obviously missing from the jekyll options, there is a setting which does something similar - show future dated posts.

In _config.yml, add

future: false

This will hide future dated posts from your live blog.

To get a local preview, simply start jekyll with

jekyll --auto --server --future

Since we don’t actually want the post to automatically appear on a future date, the published date will need to be set well into the future - while technically it is possible that all my unfinished drafts will show up in a thousand years, it is somewhat unlikely.

The post filename contains a date, but does not need to change as it is overridden by the yaml value - this post is “2012-08-23-jekyll-drafts.md”

The yaml header is

---
date: 3012-08-23 09:14:00 +1000
layout: post
slug: jekyll-drafts
title: Jekyll Draft Posts
comments: true
categories:
  - jekyll
summary:
  Cleanly handling unpublished posts on a Jekyll blog
---

When the post is ready I simply replace the 3 with a 2 - not quite as obvious as setting published to true, but equally simple.