How I Publish My Blog
I was reading some advice on blogging a couple of months back that said: “blogging about blogging is always boring.” In general, I agree, but someone asked how I publish this blog. It is a complicated mess of tools, and I figured someone else might be able to use it as an example of what to do, or maybe what not to do.
ZenWeb
The primary tool I use for my blog is ZenWeb. ZenWeb is website authoring tool by Ryan Davis. I like it because it allows multiple renderers per file, supports fully programmatic page generation for things like my series list, and allows a ton of customization. The latest version of ZenWeb is based on Jekyll so I’ve been able to use open source Jekyll themes to do the visual design of my blog. It also does handy things like creating the year and month based directory structure for my blog.
I write most of my posts in Markdown. For things I can’t neatly do in Markdown, I’ll use erb or even straight HTML. Since ZenWeb lets me have multiple renderers per file I can mix and match these as well. My blog also makes extensive use of conditionals and includes. For example, depending on the date on a post either the MIT license or the Apache 2 license (which Google prefers) is added to the footer. This footer is only added to posts where syntax highlighting is turned on. I also have code that automatically adds links to GitHub when I put code: [link here]
in the metadata at the top of the post.
The last thing ZenWeb does for me is create an RSS feed of my blog. Initially, I had RSS so my friends could read my posts in their news feeds, but that isn’t such a common use case anymore. Instead, I have an RSS feed so that my blog can tell other applications when I update the content.
GitHub, Cron, and IFTTT
I use GitHub as the master copy of my blog. Drafts are worked on in their own Git branches or occasionally in branches for a specific series. Once a post is complete it is merged into master and pushed up to GitHub. Until this year, I published my blog manually using scp from my personal laptop. My work laptop doesn’t have SSH access to the machine where my blog is hosted so I couldn’t make updates from work.
As I increased the frequency of my blog posts this year I found I needed to be able to update posts even if I didn’t have my personal laptop. I also wanted to future date content so that I could queue up material ahead of a trip. To do this I’m using a cron task. Every few hours the server hosting my blog checks GitHub for updates. If there’s an update, it re-generates my website and pushes it to the appropriate directory. The trickiest part of this was getting the host to have access to the repo. I probably spent 2 hours trying to get GitHub deploy keys working correctly but eventually I got it working.
When the cron job runs and updates the site, the RSS feed gets updated. The RSS feed is monitored by an If This Than That applet. Until a few months ago that code would add a Twitter post to my Buffer queue and post a draft on Medium. Medium integration was phased out a couple of months ago so now it just adds to my Buffer queue. Buffer in turn is setup to post to Twitter for me at times that folks are most likely to see it. Being able to queue up Twitter content in advance has helped me moderate my tweeting rate or at least the perception of my tweeting rate.
Future Improvements
I’ll be the first to admit this system is a Rube Goldberg machine of web apps and Unix tools. Considering the number of moving parts, it is surprisingly resilient. The most common issue is 404s that happen if I start a post, put it aside for a week, and then finish it without updating the timestamps. Those problems would be easy to fix with a pre-commit hook, but I’m too lazy right now. The other main issue I have is my own impatience. When I’m particularly proud of some content, I’ll keep checking my Buffer queue to see when the tweet will be published.
Longer term I’d like to simplify the system a bit. Ideally, the cron job would take care of queuing the tweet, posting a draft to Medium, and any other post publish tasks I want. I’m working on adding some of this in a Rake task as an extension to ZenWeb, but I don’t have anything working reliably yet. This level of integration would make my life easier, but it would require any users to set up OAuth for each of these sites which is probably too much to ask. I’d love to use the tagging metadata I already have in my posts to add hashtags to tweets, but for now, this system is working pretty well for me.