One feature of Wordpress that I really liked, was the ability to easily schedule the publication of a post for a specified date and time. Another was the seperation of drafts and posts in the webinterface.
I wanted these features back, but without all the clutter the Wordpress webinterface introduced in the past versions. It admittedly got better in the last version I used1, but the damage was done.
Now, firmly settled into my Octopress
txt-only environment, I could implement these features on my own.
Tailored to my very own needs. Throwing in some sync-o-magic to keep my posts and
drafts updated across all my devices.
So if you’re into these things, follow me to see how posts get published in this corner of the Internet.
Search what other people have done
The very first thing to do, when you attempt to do anything remotely technical, is to check if other people encountered2 your current problem before you.
This incron-method was one of the first posts i found3 but it could not provide me with the seperation of drafts and the scheduling I grew so accustomed to. And I just don’t want my site to rebuild everytime I change a typo in an old post. Also: instant-thinking.de lives on kinda cheap shared webspace with no Dropbox-sync-o-matic capabilities. I would need to solve this with a different approach.
This nicely mirrors my own setup:
- A Mac mini at home, almost always on
- A MacBook Pro, almost always at home, not always on
- iPhone and iPad at home and on the go
He then continues to build the site manually via a SSH-login on his Mac and deploys the
finished site via
git push to a private git-repo at Beanstalk. From there he uses FTP to update his Website.
This sounded a bit cumbersome to me and so I came up with my own solution.
My own remote blogging setup
In additon the the queueing of posts and the separation of drafts, I added syncing across my devices to the mix. So here is what I needed to achieve:
- Keep my drafts and posts seperated
- Keep my drafts and posts synced across all my devices
- Have an easy way, to change the status of my latest masterpiece5 from draft to post
- Have an easy way, to choose a specific date and time for the publication of posts
- Have an easy way, to automate the build and deployment - no manual
sshish stuff, thank you very much
So, to first reach for the low hanging fruits:
Seperate drafts and posts
Inside each Octopress
source-folder is a
_posts folder containing all the
posts. I simply created another folder
_drafts to hold my drafts. For good measure,
I patched the
Rakefile to include a new task to create a new draft. Here is
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
Basically, this is just a copy of the
new_post task. Please notice the added
in the YAML-header. This, as documented in Octopress Blogging Basics, would prevent this post from getting
published if it was found in the
_postsfolder. This will come in handy later…
It is of course still possible to create a new draft or post any other way.
Just make sure the filename follows Octopress/Jekyll convention of
YYYY-MM-DD-post-title.markdown, include the YAML-header and you’re good to
Sync across all my devices
Which brings me to syncing. These days, this usually means Dropbox. Apples iCloud could be another option one day, but right now it does not seem like Apple is going to send some love to the filesystem part of it’s operating systems. And because virtually any iOS text editor comes with Dropbox support, the choice for Dropbox is a no brainer.
So I logged into my Mac mini at home to create a new folder in my Dropbox.
I named it, oh the creativity,
blog. Inside this folder I put
images. Viewed from an iOS Dropbox-Client, it looks
a lot like this:
These folders are actually symlinks that got created on the Mac mini like so:
1 2 3 4
When finished, the
blog-folder looks like this on the Mac mini:
1 2 3 4 5 6
On any other machine, these become actual folders:
1 2 3 4 5 6
The underscores are there to make sure that these folders won’t get deployed to
the live site. So all these folders, with the exception of
images, are kept
on the local machines. This way, all the essential folders containing my
content are in sync across anything which can talk to Dropbox.
From draft to queue to published post
So now we have a perfectly synced draft. How will this draft get to the live site? And how will this happen at a given date and time?
This will happen with the help of two YAML-properties in the frontmatter and
it_queue.rb script which lives on the Mac mini and can also be found in this
The script gets run every five minutes by a LaunchAgent6. It starts by looking
into the YAML-frontmatter of every file in the
_drafts-folder. If it finds
a post with
published:true in the frontmatter it will move it from
_queue. During this move, the script reads the date part of the
date:-property and renames the file accordingly.
Let me explain:
A draft, created by the mentioned
new_draft task on the 1st of May 2012,
would live in the
_drafts-folder as the file
2012-05-01-rant-on-some-apple-thingie.markdown. In it’s YAML-frontmatter it
would carry the following properties7:
After some work on it, I decide to mark this draft as finished on May, 15th by changing the properties to:
Next time the script runs, it moves the file to the
2012-06-12-rant-on-some-apple-thingie.markdown in the process.
date: property not only defines the filename of the post, but also it’s
publishing date and time.
This is, because
it_queue.rb also checks the YAML-frontmatters of the posts
_queue-folder. Here, it scans for the date and time of the
property, transforms the found string into a Ruby time object and checks, if
this object is in the past or in the future of
Time.now. If it is in the
future, nothing happens. If it is in the past, the
build-variable is set to
1 and the build and deployment of instant-thinking.de is triggered.
The file in question would trigger the build on the first run of the script
after June 12th, 2012, 09:00. During this run, the file gets moved out of
_posts. From there, it will get rendered and put on the live
Wrapping up the build and deployment
Both parts, build and deployment, turned out to be a bit more tricky than I thought…
The problems I encountered are nonexistent, if I go manually through the steps needed to build and deploy the site. But everything goes south when the LaunchAgent tries to automatically do it’s duty.
It all comes down to the environment used when the neccessary actions are performed. Things that needed to get fixed:
- The Ruby version. The Mac mini runs OS X 10.6.8 Snow Leopard which comes with Ruby 1.8.7. Octopress needs Ruby 1.9.2, which I installed on the mini via RVM
- The encoding. Each and every Umlaut caused the build to fail catastrophically
- The SSH authentification. I use a passwordless SSH-login for the
rsync-deployment. But the LaunchAgent has no access to the used key
To solve the problem with the Ruby version, I used the wrapper
I found at urgetopunt.com.
In the LaunchAgent, I do not call
it_queue.rb directly, but use it as the
argument to ruby, which in turn gets called with the Ruby version 1.9.2
provided by RVM. The whole LaunchAgent
plist looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Following this approach, I modified the original wrapper to include
de:DE.UTF-8-encoding just like in my own interactive sessions. This took care
of all the Umlaut-problems I encountered.
Finally, I found a hint from Linc Davis on discussions.apple.com in which he explains, how a script can be told to use an existing SSH auth socket on OS X 10.5+. This approach requires, that the given user is logged into the system each time the script runs and that the script is run either under the same account or as root but that is pretty much a given on my Mac mini.
I had to change the name of the SSH auth socket variable from
SSH_AUTH_SOCK but other than this nuisance, it worked like a charm.
My final wrapper looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
And that’s pretty much it.
The scheduling is not exact to the minute because the script only runs every five minutes and even then, the build of instant-thinking.de takes almost 15 minutes on the Mac mini.
But the fact, that I can decide when my drafts become posts and when they’ll get published is really quite convenient. This is nothing I would want to write a liveblog with, but for my usual posting frequency, it is really convenient.
Even more, if you consider that the whole Wordpress date picker thingie with
buttons and bells and whistles is replaced by two lines in a
A little Ruby-script and some tinkering with YAML-properties is all it takes to
use Octopress in a much more pleasing way. A blogging framework for hackers,
If this setup suits your needs, you can find everything you need in the Github Repo. Have fun, and if you made it down here, thanks for reading.
And, if things are going fine, solved it, too…↩
Or whatever he might fancy in the future, just make sure it uses plain text and Dropbox↩
Actually, it gets run by a wrapper script which gets run by the LaunchAgent but we’ll get to this shortly…↩
And some more of course…↩