HTML5 Micro-app for Blogging From the iPad With Textastic and Octopress

I switched to using Octopress for my blog a few months ago. Octopress, as you may be aware, is a Jekyll derivative, which means that you can maintain your blog posts offline (typically in a Git repository) as a series of text files in a simple markup format such as Markdown or ReStructuredText, and then generate plain HTML files which you deploy on your webserver.

I am running “rake watch” on the server, so that whenever I modify a file (via ssh, for example), it gets immediately picked up and the necessary pages get regenerated. Or I can write a page on a separate machine, commit it in a local git repository, and push the change to the server. So far, so good. However, I would like to be able to write blog posts on my iPad as well, preferably using Textastic, which is the best editor I’ve discovered for such purposes so far.

One of the things which makes Textastic nice, is that it has a bunch of options for easily synchronizing with a remote server: WebDAV and SFTP, among others. So I can create a file on the iPad and then easily copy it to the server. (Textastic doesn’t understand Git though, but that’s a different topic.)

So what’s the remaining problem?

Well, to create a new post, Octopress expects you to write a little piece of YAML “front matter” at the start of the file, like this:

    ---
    title: HTML5 app for blogging from the iPad with Textastic and Octopress
    layout: post
    date: 2014-04-27 18:00
    comments: true
    ---

Also, the name you give to the file needs to be in a specific format, starting with the creation date of the post. So that’s a bit of an annoying bit of boilerplate work to do for each post. It’s not a huge amount of work, but it can just be enough to reduce the motivation to write a short blog post.

How can we fix that? Well, here comes the first option — but it’s not the one I actually ended up using, so feel free to skim this part!

Option 1: using Textastic templates

Textastic actually supports document templates. So we can do the following:

  1. Within Textastic, go to the root of the “Local Files” directory and create a new folder named “#Textastic”. Note that a little ‘gear’ symbol appears on the folder icon, to indicate its special meaning.
  2. Inside this folder, create a subfolder “Templates”.
  3. Inside that subfolder, create a file named “New Octopress post.json” and give it the following contents:

    {
      "uuid": "A228D51F-2EC6-483A-8168-0FCCBD5FCC89",
        "category": "Martin's Templates",
        "templates": [
        {
          "name": "New Octopress Post",
          "fileExtension": "md",
          "snippet": "---\ntitle: ${1:title of the post}\n
            layout: post\n---\n
            ${2: write your blog post here!}"
        }
      ]
    }
    

    (Note that when I wrote that code originally, I didn’t have to start from scratch — there’s already a Textastic template for creating Textastic templates!

  4. Kill Textastic and restart it. Yes, this is annoying.

  5. You can now create a new .md file and use the “New Octopress Post” template to get started. This will fill in most of the YAML boilerplate, and place the cursor on the ‘title’ field; fill it in and press TAB to move on to the next field.

So that already reduces the amount of manual work to the point where it becomes almost bearable. However, we still need to write the filename manually, and ideally there’s a few more fields we should write in the YAML block, such as the creation time. Too much work for one blog post.

Option 2: a little HTML app

The problem is that Textastic’s templating features are just a bit too limited for what we want to do. For instance, there’s no way to insert the current date into the text.

But Textastic has another fun feature: it registers itself on the iPad as an x-callback-url protocol, so you can create new files by telling Safari to open a specific URI. For example, clicking on the following link (from a machine which has Textastic installed, obviously) will open Textastic and create a new file:

textastic://x-callback-url/new?name=hello.txt&text=Hello,%20world!

So that suggests a neat solution: we can write a small HTML page which lets the user fill in the necessary fields, does a bit of processing on them in Javascript (e.g. automatically create the page ‘slug’ from the post title) and then generates a link which creates the new post for you, filling in everything but the actual content.

Which is what I did, and the result is here.

It’s a fairly ordinary HTML file containing some Javascript, there’s no server-side processing, so you’re not dependent on my site but can just place the HTML file wherever it’s convenient.

The finishing touch: turning the page into an offline app

In fact, the most convenient place to store it would be, of course, locally on your iPad. To do that, we have to turn our web page into an offline HTML5 app, telling iOS how to cache the page and that it’s OK to run the cached copy when there’s no Internet connection.

Doing that consists of three parts. First, we need to write a manifest file, describing the components of our application. In this case, there’s just one component so the manifest is pretty simple:

CACHE MANIFEST
textasticpost.html

Note that when this file is fetched from the webserver, it must be served with a Content-Type of text/content-manifest. If you’re running Apache, you can do this by putting the following in one of your config files, or in a .htaccess file if those are enabled for your site:

AddType text/cache-manifest .manifest

Next, we need to add a reference to this manifest in the header of our HTML page:

<html manifest="textastic.manifest">

And finally, it turns out that there’s a few Apple-specific meta tags we need to add in order to get the iPad to properly treat it as an offline app. So the complete header of our HTML page ends up like this:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html manifest="textastic.manifest">
<head>
  <meta charset="utf-8"/>
  <title>Octopress template generator for Textastic</title>
  <meta name="apple-touch-fullscreen" content="YES" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
</head>

And that’s it! We can now open this page in Safari, choose “save to home screen” from the “share” menu, and then whenever we want to write a blog post in the future, we can click that icon to create a new empty page with all of the YAML boilerplate filled in.