I've tried static site generators a few times in the past, and the thing that's always stopped me from adopting them full-time for my regular blog (this one) is the overhead of maintaining something built around Git on a bunch of devices when most of my writing is spontaneous and squeezed in around the edges of other stuff. I was willing to do it with Things because it's a slower site, and the bulk of the content is developed over days or weeks.
When I got the iPad Pro I'm typing this entry on, it made me start thinking about the things I'd like to be able to do given a closer-to-real keyboard and enough screen real estate to keep my brain from freezing up when starting at everything through a 10" window. “Create and post content for a website managed by a static site generator kept in a Git repository” seemed like a pretty good test case.
Attempt 1: Paleo
Reader, my formative Internet experiences all happened on a Lear-Siegler ADM-3A+ talking to an Ultrix machine over a 300 baud modem. Consequently, when I'm confronted with a “move text from one place to another and make things happen” problem, the first place I go to is “open up a dumb terminal to some distant end where all the brains and guts are, and go from there.”
To that end, my first cut at the “maintain a version-controlled static site from an iPad Pro” problem was to find a decent terminal app and see what I could do with it. I went with Panic's Prompt, which is simple and pleasant.
I went through the hassle of setting up rbenv on shared hosting, added a few conditionals to my heretofore-mac-only
.emacs.d, and applied myself to creating a blog entry. The stuff in the Middleman workflow that involves running shell commands worked fine, which solves the most potentially labor intensive part of making a new blog entry, which is creating a file in the right place with the right starting content and a decent slug.
Sadly, Prompt and Emacs don't exactly get along. Most frustrating is that the iPad Pro Smart Keyboard doesn't even have an escape key, and Prompt doesn't seem to have any provisions for remapping opt or cmd to work as a meta key. Instead, you can opt to have it keep a soft keyboard up on the bottom of the screen and reach up to tap an
ESC key. This is as awful as it sounds.
Attempt 2: Whatever the Kids Are Doing These Days
So, the way my brain works, I usually end up deciding if something that worked well for me 25 years ago isn't working now, it's probably time to swing to the other extreme. That led me to Workflow, which is probably the closest iOS is going to get to Automator any time soon.
Workflow is pretty cool: You can drag and drop actions from a variety of iOS apps and chain together workflows. It can assign and modify variables, munge text, pass text off to other things to be munged some more, and create little Workflow applets you can launch from your home screen.
So, I set out to solve the first problem of creating a Middleman blog entry, which was the part where you set a title and then pass it through a few actions to create a decent slug. In other words, you want to start from a title of “This Is My Fantastic Blog Entry!” and end with a permalink that looks more like:
Given the ability to write a script, the things you need to do to get there are pretty simple :
- Grab the title
- Downcase it.
- Strip out all the non-word characters and replace them with dashes.
- Make sure there are never multiple consecutive dashes.
- Make sure there's not a trailing dash (because it's ugly).
- Tack on the date to the front.
- Tack on “.html.markdown” to the end.
There are things you can toss in there: For instance, since you know you need a particular date format for the “date” field of the entry, you can stash today's date in a variable for reuse. Same with the pre-munged title.
Doing that on Workflow was easy enough, but laborious: Workflow itself doesn't understand regular expressions, so it has to go talk to a third-party app that does. Since that app is a single-tasking marvel, it can't pass an input string through several transformations then pass it back: It has to receive the text, do the first transformation and pass it back to Workflow, which then decides what to do next and passes it back. Workflow and that outside app do this little dance four times. Because all of this is being done with a fascinating grassroots-driven system of callback URLs the assorted apps all understand, you sit there watching Workflow switch back and forth between apps. It can be a little dizzying.
This is going to sound weird, but that rapid flipping around between apps made me sort of hate what I cobbled together, which stopped me from going to the next logical step, which was figuring out how to hand the thing my workflow stitched together back to something that could try to get it into a Git repo.
The Editorial Way
Since I'm a compulsive iOS text editor experimenter, I had a copy of Editorial sitting around. Editorial understands Markdown, and it has some built in automation you can use to create text filters and talk to other apps. While I have no doubt that Workflow is amazing for a number of things, starting from your text editor and handing off to something else seems more elegant than starting from a different app, scurrying around between all the other apps, and then handing off to something else.
With Editorial, you just stack up actions in workflows using a drag-n-drop visual interface. It can do regular expressions, transformations, ask for text, etc. There's a very nice custom UI builder that I want to try out, which would allow me to pop up a form with fields for the title and tags, or logic for whether a file is ready to be published or just a draft. You can bind a given workflow to a hotkey, meaning it's possible to just type up an entry in (syntax-highlighted) Markdown, hit a hotkey, and constitute a proper Middleman blog entry with slug that can be handed off to a receiving app.
A little Googling yielded a Jekyll-based workflow someone had already put together that got me most of the way to where I wanted to be. It didn't do real slugs, and its front matter was a little different, but it was a simple matter to modify and produce my own
Getting It to GitHub
The other half of that workflow involved getting the newly created entry over to my Middleman site. For that, it uses an iOS Git client called Working Copy. Working Copy is free if all you want to do is browse your repos, and it costs $14.99 if you want to be able to push to them. Like Workflow, it's aware of callback URLs, so it's possible to push things into it from other apps.
Once the file is in Working Copy, you can just commit it and push it. Done.
Building the Site
Well, not quite. I wanted to automate the last mile, as well: Not only did I want to get the content into the repo, but I wanted to be able to update a local copy on my shared hosting and then run a site build.
I got a little lazy here. There's a simple PHP script you can ping with a GitHub webhook that will do the work of updating a local copy. It's not a perfect fit, but it does what I need. I stuck it off in a corner of one of my live sites. A cron job handles running a Middleman build every few minutes. Since Middleman is pretty smart about looking for changed files, it's not as expensive as a comparable Jekyll build.
Anyhow, lots of things thrown out. If you're a static site blogger looking to use an iPad or iPad Pro to write entries or maintain your Git-based site, here's the basic workflow:
- Write your entries in Editorial. It's simple but extensible.
- Use this Editorial workflow to generate entries with decent slugs and front matter.
- Use Working Copy as your Git client to receive the entries.
- Use GitHub webhooks and this simple PHP script on the server where your site is published plus cron to trigger builds.