Isotoping Sound City

Last week I was tasked by Mr. Grohl to build a real website for his upcoming Sound City documentary. And by real I mean: a place where a synopsis, cast, trailer, and other pieces of media can live and be discovered… not an FM radio or console fader.

Boo. Okay, DG.

We also needed a place to release a new series of videos in which Dave asks everyone that took part in the movie the same question: What was your first music memory? Watch this one with Kevin Cronin to see what I’m talking about. Tom Petty has the best story, but you’ll have to wait for that. ;-)

Making Magic with Isotope

Jason Kadlec of CHNL told me about this fancy jQuery layout plugin called Isotope a few weeks ago and I’ve been dying to try it. Isotope describes itself as “an exquisite jQuery plugin for magical layouts.” Magical indeed. Check out some of the ridiculous demos here.

Setting up Isotope is as easy as adding a container of items to your site and calling isotope via jQuery on that container, providing the class of the items within:

$('#isotope').isotope({
  itemSelector: '.item'
});

Isotope sniffs out a default column width from your first item, but you’re better off defining this yourself within your CSS. I chose to use one column width for all my items, but Isotope is smart enough to understand a dynamically changing width. Just remember, padding counts towards your total width.

Isotope also has an insanely smart filtering engine powered by simply adding classes to your items. For example, here’s how I would define Tom Petty’s “Musical Memory” video:

<div class="item video musical-memory tom-petty">
  <!-- Video content here -->
</div>

I could then easily create buttons on my page that sort the Isotope to each particular class. [1] In my case, allowing visitors to filter by content type, category, and even cast member. [2] So easy, so awesome.

Special thanks to Jason for the tip and David DeSandro for writing the plugin!

Balancing the Design

Neve Console

The Isotope container is a heavy piece of real estate and you’ll need to balance any other elements by adding a bit of weight to them. I did this by adding a thick border to the left side of my sidebar. I feel like this allows the sidebar to live next to the Isotope without feeling out of place. Alternately, you could try designing a lighter Isotope layout, void of any thick paddings or heavy colors.

Aesthetically, I’ve brought in some of the elements I’ve been setting up throughout the campaign such as the dark theme and “tape” textures taken from the actual Sound City fader. [3] I think these simple guidelines lend themselves well to the actual content being featured on the Isotope.

Generating the Content

Great… but, where does the actual content come from?

Well, you could manually add the items to a static page as needed, but that’s just dumb. Instead, you’ll want to to dynamically update the Isotope with a database of content and the categories they belong to.

I considered developing my own own for about two seconds before I realized the Tumblr API was built for this shit. In addition to providing all descriptions, tags, and associated media, Tumblr also distinguishes between several post types: text, photo, quote, link, chat, audio, and video. This makes their infrastructure perfect for Isotope. So, after creating a few ICanHaz.JS templates for each content piece:

<script id="video" type="text/html">
  <div class="item video">
    <a href="{{ permalink_url }}" target="_blank">
      <img src="{{ thumbnail_url }}" />
    </a>
  </div>
</script>

I was able to connect a simple Tumblr API call to a case loop that generated HTML from each associated post type template, which was then appended to the Isotope.

$.getJSON("http://api.tumblr.com/v2/blog/TUMBLR_URL/posts?api_key=KEY", function (data) {
  posts = data.response.posts;

  for (i = 0, len = posts.length; i < len; i++) {
    switch (post.type) {
      case "quote":
        html = ich.quote(post);
        break;
      case "video":
        html = ich.video(post);
        break;
    };

    $('#isotope').append(html).isotope('insert', html);
  }
});

So why not just use Tumblr altogether?

Honestly, I hate their theming engine. However, I’m thinking that once this thing is perfect, I could possibly write a script that generates a Tumblr theme from the provided layout and templates. That could be rad.

Let’s get Real_time_, Son

After digging through Tumblr’s poorly documented real-time API, I finally found a solution that would allow me to dynamically add items to the Isotope as they were posted to Tumblr. I used a combination of Superfeedr and Pusher to do this.

First, we need to configure both Node package modules on our server:

// Configure Pusher
pusher = new Pusher({
  appId  : APP_ID,
  key    : KEY,
  secret : SECRET
});

// Configure Superfeedr
superfeedr = new Superfeedr(USERNAME, PASSWORD);

Then we can connect both:

superfeedr.on 'connected', function () {
  // subscribe to the sound city feed
  superfeedr.subscribe('http://TUMBLR_URL/rss', function (err, feed) {
    // subscribed ...
  }),

  // on each notification...
  superfeedr.on('notification', function (notification) {
    // trigger an action of tumblr on the soundcity channel
    pusher.trigger("soundcity", "tumblr");
  })
};

And finally, back on the client, we’ll user Pusher’s JavaScript library to listen for Tumblr activity. For each ping we get, we should ask Tumblr for the newest post and add it to the Isotope.

// Configure Pusher
pusher  = new Pusher(APP_ID);
channel = pusher.subscribe('soundcity');

// Listen for new Tumblr post...
channel.bind('tumblr'), function (data) {
  // Get the newest post from Tumblr and add it to Isotope
});

So now, when I take a Sound City photo with Instagram and make sure Tumblr is connected, once posted, the photo will automatically show up on the front page of Sound City. Probably unnecessary, but bad ass, and surely you’ll grab that visitor’s attention when the layout goes all Minority Report on their ass.

Looking Ahead

The current setup works, but it’s far from perfect. I plan on redeveloping the entire client side infrastructure with Backbone.JS in anticipation for adding one-click media streaming to the video and audio items. Backbone will also help simplify the template rendering process.

Sign-up if you’d like to hear more on that in the future!


[1] Using jQuery BBQ, you can create a bookmark-able hashed URL history for each filter. Instructions here.

[2] Since the Sound City documentary has so many participants, I thought it would be neat to auto filter the site to a particular cast member depending on where referral traffic comes from. In other words, if you clicked a link to the site on tompetty.com, you would see Tom Petty content near the top. This is probably a bad idea, but worth some A/B testing regardless

[3] Shoutout to Flood Standard for being the perfect typeface for highlighter tape writing.

 
134
Kudos
 
134
Kudos

Read this next

Waveforms, Let’s Talk About Them

I’ve worked at SoundCloud for over two years now, and if there’s one thing I do a lot, it’s color waveforms. Tons of them. And, I’ve done it several different ways. Today, Johannes and I are pumped to announce a... Continue →