Blog Shortcuts

Featured image

I use a couple of Shortcuts to make drafting and managing my blog easier. Truth be told, getting to play around with Shortcuts and iOS automation in general was one of the reasons I started this blog.1

The basic process for writing my blog is:

  • Draft the post in Markdown using iA Writer
  • Commit the post into the develop branch and push to GitLab using WorkingCopy
  • GitLab then runs a pipeline to deploy the blog to my staging server2
  • Review the staging server to make sure I’m happy with the results
  • Open and close a Merge Request on Gitlab to merge develop into main
  • This triggers another pipeline that deploys to the production server—the one you’re on right now

To help with that workflow I’ve created two shortcuts; ‘New Blog Post’ and ‘Upload Files to Blog’. Hopefully their names are self explanatory.

New Blog Post

I didn’t want to have to create the boilerplate each time I started a new blog post. Hugo, which I use for my blog, has a command for doing that (hugo new posts/my-first-post.md) but I can’t run that on my iPad. Instead I replicated that using Shortcuts.

Name for the new post

Firstly I need to get the name of the new post. This then needs to be converted to lowercase, change spaces into hyphens and have any characters that aren’t letters, numbers or hyphens removed.

I then get the description for the post but that’s not interesting so no screenshot for that.

Tags

I then get a list of space separated tags. I don’t know whether the stripping of any excess whitespace is necessary but it shouldn’t cause any harm. I then concatenate the list of lower-cased tags with commas and store the value in a variable.

Header

I combine these values into a MultiMarkdown header block and present these values back to make sure they’re right. If they’re not correct, I end the shortcut. I might revisit this at some stage to “restart” the shortcut if the values are incorrect but at the moment it’s not a huge impost to start again.

Git Checkout

Now the fun part. Using Working Copy I switch to the develop branch, fetch from the remote, merge the remote into my local copy and create the file for the new blog post. I also use Secure ShellFish to create a new directory on my server to store images in.3 Finally the file is opened up in WorkingCopy ready for me to then edit it in iA Writer.

Upload Files to Blog

This shortcut allows me to upload files to my blog either from the Shortcuts app or the Share sheet. I’ve written about this shortcut previously and you’ll see this updated version fixes a few of the TODOs I listed on the old post.

Directory List

First I retrieve a list of the existing directories on the server using Secure ShellFish. I present this list of directories with a further option to create a new directory on the server. I strip the first part of the path (/data/blog/files) because the upload server is setup to place anything under that path.

Choose a Directory

I then iterate over each of the files that were passed in to the shortcut or selected from the file picker and ask where the file should be uploaded to. Currently I ask which directory to save in for each file but given it’s likely all files will be related to the same blog post I may change this option to only select the directory once.

New Directory

If the new directory option is chosen then I ask for the name of the new directory ensuring a trailing slash is added.

Upload file

The user4 is asked to pick a name with the default value being the existing file name. I’m not sure why the default value for a file doesn’t return a combined filename.extension but it doesn’t.

The file is POSTed to the server which returns the URL in the JSON response which is converted into a Markdown URL.

{"url": "https://domain.com/path/to/file.png"}

Copy result to clipboard

The combined results are copied to the clipboard so I can paste them directly into a blog post.

Using this shortcut has made crafting an image heavy post, like this one, much easier. I realised I can upload directly from the iPad’s screenshot interface using the share sheet which means I can take a screenshot and upload to the blog without having to save the screenshot first meaning less screenshots cluttering my Files and Photos apps.

For some reason I can’t get photos stored in Photos to work with this Shortcut. I’m assuming they aren’t the same type of object as one that’s returned from the file picker. I’ll have to investigate that more.

And That’s It

That’s how I use Shortcuts to automate parts of my blogging workflow. I don’t think there’s anything particularly new or groundbreaking but it was fun putting it altogether.

Interestingly what I’ve found is that due to Shortcuts, it’s easier to start a new blog post on my iPad than on my Mac.5 I could create scripts on my Mac to do the same things but I haven’t wanted to yet. The combination of Shortcuts and the single focus of the iPad mean it’s a lot more enjoyable to sit and write on the iPad than at my Mac.

Bonus Shortcuts

Get HTML Source

If you clicked on the link to my previous post about shortcuts you’ll notice it links direct to the heading about the Shortcut. In order to find out what that link needed to be I had to get the HTML source of the page which unfortunately Safari doesn’t support. If you Google for an answer most of them are almost a decade old talking about installing a Javascript bookmarklet which I didn’t want to do.

I figured it had to be doable in Shortcuts. And while it is, it’s a weird way of doing things.

Choose a URL

Firstly the boilerplate which allows passing a URL to the shortcut via the Share sheet or asking the user for a URL—default being what’s on the user’s clipboard.

Make HTML from Content

Then request the website, convert Rich Text to HTML6 and show the results.

In true programmer style I wrote my own implementation of this then discovered there’s a version available through the Shortcuts Gallery. Oh well, at least I learned something.

I wanted to have confidence that any links I add to a blog post work. The shortcut below extracts Markdown links from text passed into it and verifies they work.

Extract URLs from Text

I use a number of regexes to extract Markdown links from the text as well as the URL to the featured image for the post.

Iterate over URLs

Then I iterate over each of the links and use the Query function from Toolbox Pro to verify the links can be reached storing the result in a dictionary. If a link fails, I ask for confirmation to continue.

View Results

Finally, and I’m not sure whether this will ever be useful, I present the results for each of the links on whether they worked or not and offer to save the results to the clipboard. To get meta, a sample of those results for this blog post is included below.

Checked 26 URLs on 13 Aug 2020 at 10:29 pm
=================
https://blog.aselford.dev/files/posts/blog-shortcuts/make-html.png: found
https://workingcopyapp.com/: found
https://toolboxpro.app/: found
https://gohugo.io/: found
https://github.com/ezzizzle/uploadserver: found
https://secureshellfish.app/: found
https://blog.aselford.dev/posts/uploading-files-to-the-blog/#uploading-from-ipad: found
https://ia.net/writer: found

And that’s how I verify my links work (or at least return an 🆗 response code).

I would love a way to trigger this Shortcut with a keyboard shortcut but I think the limitations of iOS mean that’s not currently possible. Would love to be proven wrong though.

In writing this post I realised there is a way to trigger this Shortcut from a keyboard shortcut (kind of). Given the shortcut can accept text on the clipboard I can:

  • ⌘ + a - Select all text in iA Writer
  • ⌘ + c
  • ⌘ + Space - Bring up spotlight
  • "verify links work" Enter - run the shortcut

While a single keyboard shortcut would be nice, this will do for now.


This blog post ended up being a lot longer than I had anticipated…


  1. Taking great inspiration from MacStories of course. ↩︎

  2. If I can be bothered, I might start putting posts in their own branch and merge them into main once complete. If I do that, I could try and use GitLab’s built in Kubernetes integration to deploy each branch to its own hostname. 🤔 Sounds fun actually… ↩︎

  3. I know, I know, this isn’t great just creating directories on the server using SSH. I’ll make it better some day. ↩︎

  4. It’s weird to say ‘the user’ when I’m the only user. ↩︎

  5. This means I tend not to want to start any new posts on my Mac and have been known to start the post on my iPad, push to GitLab and then pull to the Mac. ↩︎

  6. Why does the ‘Get Contents of URL’ return Rich Text and not HTML? Or at least why can’t I choose to return HTML? ↩︎