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 lukelov.es 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 lukelov.es 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)
super
access_token_file = File.expand_path "../.instagram_access_token", File.dirname(__FILE__)
@access_token = File.open(access_token_file).gets
@image_res = "standard_resolution"
@markup = markup
@cache_folder = File.expand_path "../.instagram-cache", File.dirname(__FILE__)
FileUtils.mkdir_p @cache_folder
end
def render(context)
id = @markup.strip
media = get_cached_media(id) || get_media(id)
gen_html_output JSON.parse(media)
end
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 = Time.at(Integer(media["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='http://instagram.com'>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='http://maps.google.com?q=#{coords}'>"
output += "<img border='0' "
output += "src='http://maps.googleapis.com/maps/api/staticmap?center=#{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}"
end
output += "</p>"
end
output += "<p><a href='http://web.stagram.com/p/#{id}#photo#{id}'>Leave a comment</a></p>"
end
def get_cache_file_for(id)
File.join @cache_folder, "#{id}.cache"
end
def cache(id, data)
cache_file = get_cache_file_for id
File.open(cache_file, "w") do |io|
io.write data
end
end
def get_media(id)
client = Instagram.client(:access_token => @access_token)
data = client.media_item(id).to_json
cache id, data unless @cache_disabled
data
end
def get_cached_media(id)
cache_file = get_cache_file_for id
File.read cache_file if File.exist? cache_file
end
end
end
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 lukelov.es). 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 lukelov.es.