Instagram Liquid Tag Plugin for Jekyll and Octopress

Being new to the world of Ruby (and obviously Jekyll), I thought a good initial learning experience would be to write a liquid tag for Jekyll to display an Instagram photo. I finished up a decent enough version of the code, and it’s actually in use over at to display all my Instagrams. Check out this page for a complete example of what the finished product looks like.

It is a simple liquid tag which takes one parameter, the ID of a media item from Instagram. The code then fetches the media item using Instagram’s ruby gem, and writes a bunch of relevant HTML to the page.

I currently have it displaying:

  • the 612x612 version of the image (which links to the photo on Instagram)
  • the filter used to create the image
  • a static map of where the image was taken using the Google Static Map API
  • the name of the location where the image was taken
  • a link to comment on the Instagram using webstagram

Obviously, the location information is only displayed if the Instagram has that data associated with it.

The embedded gist below should be the same as the code being used in the repository.

If you have questions, comments, bugs, etc, please leave a comment on this post or the gist, and if you’d like to contribute fixes or features directly, you can submit a pull request for this file.

# A Liquid tag for Jekyll sites that allows embedding Instagrams
# by: Luke Karrys
# Example usage: {% instagram media_id %}
require 'instagram'
require 'json'
module Jekyll
class InstagramTag < Liquid::Tag
def initialize(tag_name, markup, token)
access_token_file = File.expand_path "../.instagram_access_token", File.dirname(__FILE__)
@access_token =
@image_res = "standard_resolution"
@markup = markup
@cache_folder = File.expand_path "../.instagram-cache", File.dirname(__FILE__)
FileUtils.mkdir_p @cache_folder
def render(context)
id = @markup.strip
media = get_cached_media(id) || get_media(id)
gen_html_output JSON.parse(media)
def gen_html_output(media)
loc_name, lat, lon = nil, nil, nil
id = media["id"]
link = media["link"]
src = media["images"][@image_res]["url"]
image_w = media["images"][@image_res]["width"]
image_h = media["images"][@image_res]["height"]
location = media["location"]
filter = media["filter"]
caption = media["caption"]
created =["created_time"])).strftime("%I:%M%p %B %e, %Y")
title = caption ? caption["text"] : "Untitled Instagram"
output = "<p><a href='#{link}'><img src='#{src}' alt='#{title}' /></a>"
output += "<br/>Filtered with #{filter} through <a href=''>Instagram</a></p><!--more-->"
if location
loc_name = location["name"]
lat = location["latitude"]
lon = location["longitude"]
coords = "#{lat},#{lon}"
loc_alt = loc_name || coords
output += "<p><a href='{coords}'>"
output += "<img border='0' "
output += "src='{coords}&markers=#{coords}&zoom=14&size=#{image_w}x200&sensor=false' "
output += "alt='#{loc_alt}' /></a>"
if loc_name
output += "<br/>Taken at #{loc_name}"
output += "</p>"
output += "<p><a href='{id}#photo#{id}'>Leave a comment</a></p>"
def get_cache_file_for(id)
File.join @cache_folder, "#{id}.cache"
def cache(id, data)
cache_file = get_cache_file_for id, "w") do |io|
io.write data
def get_media(id)
client = Instagram.client(:access_token => @access_token)
data = client.media_item(id).to_json
cache id, data unless @cache_disabled
def get_cached_media(id)
cache_file = get_cache_file_for id cache_file if File.exist? cache_file
Liquid::Template.register_tag("instagram", Jekyll::InstagramTag)
view raw instagram.rb hosted with ❤ by GitHub

On a side note, I also came up with a solution for how to batch create Instagram posts (as you might’ve noticed by the hundreds of Instagram posts on The solution was to create a few Rake tasks similar to the ones that are already being used by Octopress to create new posts and pages. I will be writing another blog post soon detailing those and how they work, but if you would like a sneak peak, checkout the Rakefile for