Importing Instagram Photos Into Jekyll

I often post photos to Instagram or Unsplash. Now that I'm using my website for microblogging, I've started publishing my photos here as well. I'll have more ownership over the content and, should either of these services ever go away, my photos will still be available.

I've also imported into my website a copy of all the photos I've posted to Instagram–about 1,200 photos spanning almost eight years. To do this, I requested an archive of all my Instagram data, copied the photos to my site, and generated all of the posts using Shortcuts.

The ZIP archive provided by Instagram contains a copy of everything uploaded, along with JSON files containing data about each post, comment, like, and more. While the archive contains all of this data, I was only interested in the photos.

Extracting the photos

The archive's photos/ directory is neatly structured, with all photos organized into subdirectories using a YYYYMM date format (e.g., 201804/). The media.json file contains a photos dictionary, where each item contains information about each photo1:

  • path: The relative path to the photo.
  • location: The location the photo was tagged with. This is blank if no location was specified.
  • taken_at: The date the photo was posted.
  • caption: The caption of that photo. Similar to location, this is blank if no captiion was included.

The first step was to import all the photos into the media/ directory of my website. I extracted the archive using Documents on my iPad , then created a new ZIP file containing just the photos/ directory. I opened this in Working Copy and extracted this new archive into my website's git repository. After committing and pushing the changes, all of those photos were live and available to link to.

Creating the posts

Next, I copied media.json to iCloud Drive, then used Shortcuts (née Workflow) to create this shortcut that performs the following actions:

  • Loops through every item within the media.json file's photos dictionary.
  • Gets the value for each item's path, location, taken_at, and caption.
  • Creates a text file for each photo with the required Jekyll front matter using the values retrieved above, and sets the category to photo. The caption, if available, is included in the post.
  • Sets an appropriate name for the text file, based on the date information from taken_at.
  • Creates a ZIP file of all the text files that have been generated.

This is an example of a text file that the shortcut generates:

---
layout: microblogpost
category: photo
date: '2018-09-02T14:54:40'
title: ''
slug: '18090212145440'
mf-photo:
  - https://www.jordanmerrick.com/media/instagram/photos/201809/e22680154ef0b993e870789b69764673.jpg
---
I love Central Park
...

The photo URL is included in mf-photo as I'm using the same template I use for microblog posts, and that field was established when I set up the Micropub to GitHub service I use. You can easily change this to whatever you need.

Once complete, I opened the archive in Working Copy and extracted it into my site's microblog/_posts/ directory.

Making changes to my Jekyll template

With my photos imported, I made a few small tweaks to my Jekyll template files. My microblog archive page displays a 10-word excerpt of the micropost's text and uses it as the post's link. However, many of my photos had no caption. As a result, there was no text to create an excerpt from, so Jekyll was skipping them and they weren't being listed.

To make sure all my photos were listed on my archive page—and distinguish between plain text and photo posts—I added an emoji icon for any microblog posts that have the photo category set. I also edited the template for individual microblog posts to display the location information (along with the emoji pushpin symbol), if available.

Finally, I created additional JSON and RSS feeds that only include microblog posts with photos.

  1. Instagram treats posts with multiple photos as separate posts in the data archive. That was fine for me, as I've used only that feature maybe two or three times. 

Webmentions

No webmentions received.