Publishing with WP-MD

One of the reasons I had been running this site on was due to the way plain text files were handled. I had a single folder in Dropbox that contained all of my posts as MultiMarkdown files, and monitored that folder for changes, which were immediately reflected on the site. In moving to WordPress, I wanted to find a way to maintain a canonical local folder of posts.

I started out looking for a WordPress plugin that could help me. The Post via Dropbox plugin looked interesting, but it had a few quirks that I knew I wouldn’t be able to live with:

  1. I didn’t like the way revisions were handled. Since the plugin doesn’t provide a method for getting the post ID, this seems like a very inelegant solution. I would have to go off to the admin panel to track down the ID of the post before being able to revise the document:

    You need to specify the ID of the post, there’re two ways: 1) using [id] tag or 2) prepend to filename the ID (example: 500-filename.txt). The quickest way to edit an existing post, already posted via Dropbox, is to move the file from the subfolder ‘posted’ to the principal folder.

  2. I didn’t like that the format for the post metadata isn’t MultiMarkdown compatible. Instead of the key and value structure of MultiMarkdown metadata, Post via Dropbox uses a HTML-style tags:

    Why WordPress is able to read informations in proper manner, you must use some tags like [title] [/title] and [content] [/content].

I didn’t find any other plugins that looked like they were going to operate the way that I wanted, so I started to look into how I might be able to leverage the metaWeblog XML-RPC API. That’s when I remembered that Dr. Drang had written a bunch of posts about his scripts for blogging from BBEdit.

Dr. Drang’s WP-MD BBEdit package contains a lot of tools, but there were three scripts in particular that made me feel like I’d be able to get along with WordPress:

  1. Publish takes a MultiMarkdown file with incomplete metadata, publishes it to WordPress, and fills in metadata in the file (including the post ID). Repeated calls leverage the existence of the post ID to update the proper post.
  2. recent-posts returns the titles and post IDs of, you guessed it, recent posts. So, if I end up posting something from the admin panel of the site, this script provides an easy way to grab the post ID when I get back to my computer.
  3. get-post returns the metadata and content associated with a post ID. This, paired with recent-posts, allows for the generation of a canonical local file for posts that originate somewhere else.

Armed with these tools, I felt like I would be able to properly maintain a complete, canonical, local copy of all of my posts as MultiMarkdown files. The next challenge was to get them up and running.

Dr. Drang provides great documentation for these tools in a pair of posts. This post details Publish, and this post goes into the other tools. Additionally, the Github Repo contains thorough notes on which scripts require modifications. His writing assumes some knowledge of Python, but since I’ve never really worked with Python before, I figured I’d try the detailed steps I used to get started1.

  1. I installed Python (and pip) via Homebrew (I used the GUI tool Cake Brew). I don’t think pip is part of the standard OS X Python installation, which is why I opted to follow the Python Guide installation steps.

  2. With pip installed, I was able to use it to install the keyring and pytz libraries required for the scripts:

    pip install keyring
    pip install pytz
  3. I ran the interactive session detailed here, to create a Keychain entry for the credentials for this site:

    import keyring
    keyring.set_password('', 'myname', 'mypassword')
  4. I installed the WP-MD package. Dr. Drang details this process here. I put the package in Dropbox, so that it would stay in sync between my laptop and iMac.

  5. I customized the scripts for my site:

    • All three scripts needed to be pointed at the Homebrew Python installation, by changing the first line from #!/usr/bin/python to #!/usr/local/bin/python.
    • All three scripts needed the url and user variables to be customized. I set url to, and user to myname.
    • get-post and Publish both require specifying a timezone. This Stack Overflow post provides a complete list of available timezone specifications.

With this setup, I was able to make a few minor (manual) modifications to my files and publish them to WordPress.

  1. This is almost entirely for me, in case I ever need to go through this process again.