Schedule posts in Jekyll

In my previous posts about Jekyll I explained what is Jekyll, how I installed it and that I wanted to be able to schedule a post to be published later.

So I decided to write a plugin for that. There is two elements in it, first the plugin itself and a bash script. The plugin write a file with the publication date of next post. The bash script is executed by a cron on a regular basis, read the file with the next post date and rebuild the site if necessary.

Here is the plugin, called schedule_build.rb:

module Jekyll
  class Post
    alias_method :pre_initialize, :initialize
    
    def initialize(site, source, dir, name)
      pre_initialize(site, source, dir, name)
      if site.config['no_schedule']
        site.config['next_build'] = nil
        return
      end
      if self.data.has_key?('no_schedule') && self.data['no_schedule'] == true
        return
      end
      if (Time.new <=> self.date) < 0
        if self.published
          next_build = site.config['next_build']
          if next_build == nil or (next_build <=> self.date) > 0
            site.config['next_build'] = self.date
          end
          site.config['next_build']
        end
        self.published = false
      end
    end
  end

  class ScheduleBuildGenerator < Generator
    def generate(site)
      next_build = site.config['next_build']
      date_file = File.join(site.dest, 'next_build.txt')
      if !(next_build == nil)
        f = File.new(date_file, 'w')
        f.write(next_build.strftime("%s"))
        f.close
        site.static_files << Jekyll::StaticFile.new(site, site.dest, '', 'next_build.txt')
      end
    end
  end
end

As you can see, each post update a next_build variable if their publication date is in the future and more recent than current next_build value.

Then the generator write a file called next_build.txt in _site directory with this date in it.

When writing your post you can put no_schedule: true in your _config.yml if you want to have all your future posts to be generated. Likewise, put no_schedule: true in your post to have it generated even if it's in the future.

Now we just need a script schedule_build.sh (with execution right) to rebuild the website if necessary:

#!/bin/bash

next_build_date=`cat /srv/blog.example.com/_site/next_build.txt`
current_date=`date +%s`

if (( $current_date > $next_build_date )) ; then
  ~/blog.example.com.git/hooks/post-receive
fi

Here the script calls the script that is building the site when something is pushed in git.

Add it to cron and you are done.

This plugin is available on github.

Comments Add one by sending me an email.