Jekyll Draft Publishing Plugin

I’ve migrated this blog (again, I know) and have finally settled on Jekyll and Markdown as my publishing platform. The only thing I didn’t like about it was the lack of a quick publishing workflow for my drafts, so I wrote a small plugin to handle the process.

First off, I added a _drafts and a _publish folder to the root of my Jekyll install:

.
|-- _config.yml
|-- _drafts
|   `-- jekyll-draft-publishing-plugin.md
|-- _includes
|-- _layouts
|   |-- default.html
|   `-- post.html
|-- _posts
|   |-- 2013-01-28-mklocalsearch-example.md
|   `-- 2013-1-31-generate-xcode-warnings-from-todo-comments.md
|-- _publish
|-- _site
`-- index.html

Next, I added the following publisher.rb plugin to the _plugins folder:

module Jekyll
  class PostPublisher < Generator
    safe false
  
    def replace(filepath, regexp, *args, &block)
      content = File.read(filepath).gsub(regexp, *args, &block)
      File.open(filepath, 'wb') { |file| file.write(content) }
    end
  
    def generate(site)
      @files = Dir["_publish/*"]
      @files.each_with_index { |f,i| 
        now = DateTime.now.strftime("%Y-%m-%d %H:%M:%S")
        replace(f, /^date: unpublished/mi) { |match| "date: \"" + now + "\"" }
        now = Date.today.strftime("%Y-%m-%d")
        File.rename(f, "_posts/#{now}-#{File.basename(f)}") 
      }
    end
  end
end

Gist Source: https://gist.github.com/4689219

With this in place, I can leave the date off my draft file name, for example:

_drafts/jekyll-draft-publishing-plugin.md

and when I finish writing the post, I just move it to the _publish folder.

_publish/jekyll-draft-publishing-plugin.md

The Jekyll plugin takes care of adding the Y-m-d to the beginning of the file and moves in into the _posts folder.

_posts/2013-02-01-jekyll-draft-publishing-plugin.md

Also, for more accurate date sorting my default YAML template includes a date: unpublished tag:

---
title: ""
date: unpublished
layout: post
tags:
--- 

Post content

The publisher.rb plugin automatically replaces date: unpublished with a timestamp when the post is published:

---
title: ""
date: "2013-02-01 09:29:16"
layout: post
tags:
--- 

Post content

This simplifies a few steps in the workflow, removing the manual date entry and I can use dropbox and iOS apps to manage the _drafts and _publish folders while Jekyll can run on a different machine to update the site.

Next I’ll update the plugin to allow scheduling posts for the future.