Andrei Mackenzie

Andrei Mackenzie

Engineering Manager at Xandr

06 Feb 2011

A Twitter Feed on Jekyll

I’ve been looking at options for integrating a Twitter feed on to this site. I first experimented with the Twitter REST API directly through JavaScript. While the API itself is great, I found that I would have had to include a library to parse the JSON. Including something like jQuery seemed silly for a single feature. I also prefer a solution that generates the feed server-side. Generating the feed on the server allows the page to load all at once and eliminates the potential complication of a browser with JavaScript disabled.

I decided to implement this approach. A Ruby script is used to generate static HTML containing Twitter data. This script can be scheduled to run as often as desired via cron job. Once the data is available, it can be inserted into a Liquid template just like any other HTML. Although some of the up-to-the-second dynamism of Twitter is lost, this seems like a much more Jekyll-ish way of approaching the problem. Since static pages are only regenerated when desired, calls to the outside Twitter API are minimized.

The Script

This is the script I use as part of the site regeneration process. This script requires the yajl-ruby library to process the JSON. I tied the script in to my build process via a make target.

##!/usr/bin/env ruby
require "rubygems"
require "twitter"
require "yajl"
require "time"

screen_name = "ScreenName"
num_tweets = 5
output_file = "/path/to/jekyll/instance/_includes/twitter.html"

# Returns an HTML string of tweets with dates inside <p> tags
def get_tweets(screen_name, num_tweets)
    result = "<h2>On Twitter...</h2>\n"

    #Query num_tweets tweets from screen_name and create the HTML
    Twitter.user_timeline("ScreenName", {"count" => num_tweets}).each do |tweet|
    date = Time.parse(tweet.created_at).strftime("%d %b %Y - %H:%M:%S")
    result = result + "<div class=\"tweet\">
                         <p class=\"content\">
                           <img src=\"#{tweet.user.profile_image_url}\" alt=\"Twitter Icon\"/>
                           <span>#{tweet.text}</span>
                        </p>
                        <p class=\"date\">posted on #{date}</p>
                      </div>"
    end

    return result
end

output = get_tweets(screen_name, num_tweets)
File.open(output_file, "w") {|f| f.write(output) }

The twitter.html can then be included in any template using Liquid’s include.