Build Your Own Social Home!

Avatar of Chris Coyier
Chris Coyier on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

Many of us have many “homes” on the interwebs. Personally I use Twitter, Flickr, ScrnShots, and Facebook. These web services are cool enough to offer ways to interact with them and pull data out of them without even necessarily visiting the site itself. This is called an API (or Application Programming Interface).

View Demo   Download Files

Update November 2011 – ScrnShots is shutting down. I simplified this demo, brought jQuery up to date, and replaced ScrnShots with Dribbble. I also chucked it on GitHub if anyone wants to add more. The tutorial below still stands fine I think.
Update January 2013 – Updated to fix Twitter API.
Update July 2013 – The code below no longer works as-is with the Twitter API update to 1.1 as of 2013-06-11. The 1.1 API requires oAuth which requires a server side component. Here’s a PHP way to interact with the new API. If I get some time I’ll update this demo.
Update July 2014 – Here’s a JavaScript way, albeit a bit hacky.

You can think of an API as a lot like an RSS feed. If you read CSS-Tricks through a feed reader like Google Reader, you know that you don’t even need to visit the site to read my content, because that data is being served up another way. In the case of RSS, it’s an XML file formatted in a very specific way. API’s are often served up as XML, formatted however that particular application thinks it will be of most use to you. XML is cool, but much like HTML, it needs to be parsed before you can really do anything with it. Enter JSON.

JSON (JavaScript Object Notation) is what all the hip applications are serving up these days with their API’s as an alternative to XML. The cool part about JSON is that you don’t need to parse it in the same way you do XML. That data you get from a JSON call comes back as an object all ready-to-rock and let you do stuff with it. Note: if that was way off or a bad explanation, feel free to correct me.

Using APIs (jQuery and JSON)

jQuery provides a dead-simple way of retrieving these JSON objects

$.getJSON('http://url-to-api.com', function(data){
  $.each(data, function(index, item){
    // do stuff with each item
  });
});

The code above hits the URL provided (you’ll need to replace that with a real URL to a real API that spits out real JSON of course) and then does a loop through each “item” and gives you a chance to do something with that item. I say “item” because while that is a common name that APIs use, isn’t always the case, and you’ll need to be specific and accurate here as JSON provides very little in the way of error handling.

Inserting Stuff Onto Your Page

Another reason to use jQuery here is because of how is it makes it to insert HTML onto the page on-the-fly. Let’s take a look at the code example for grabbing recent “tweets” from Twitter and then use the built-in jQuery function append() to get them on the page.

$.getJSON('https://api.twitter.com/1/statuses/user_timeline/chriscoyier.json?count=10&include_rts=1&callback=?', function(data){
	$.each(data, function(index, item){
		$('#twitter').append('<div class="tweet"><p>' + item.text + '</p><p>' + item.created_at + '</p></div>');
	});
});

This will put a new div of class “tweet” onto the page (inside the parent div of ID “twitter”) for each “item” in the object. Notice the “count” variable in the URL which Twitter provides. It is set at 10 which will return 10 items thus there will be 10 divs on the page. Inside of those div’s we have two paragraph elements. One with “item.text” and one with “item.created_at”. These will be the actual text of my last tweet and when I submitted it.

Example of resulting HTML from one item:

<div class="tweet">
  <p>I wish position: relative; worked for table cells =P</p>
  <p>1 day ago</p>
</div>

Now that’s more like it! We can use our CSS skillz to style that up however we want. Like this perhaps:

.tweet { 
   padding: 10px; 
   margin: 5px 0; 
   background: url(images/transpOrange25.png);
}

Extending The Idea

Let’s make three div’s on our page, one for Flickr, one for Twitter and one for ScrnShots. Then we’ll use our jQuery + JSON technique to fill them up.

Base HMTL:

<body>
	<div id="page-wrap">

		<div id="flickr">
			<h1>Flickr Photos</h1>
		</div>
		
		<div id="twitter">
			<h1>Twitter Updates</h1>
		</div>
		
		<div id="scrnshots">
			<h1>Latest ScrnShots</h1>
		</div>
	
	</div>
</body>

Now heres the jQuery to pull in and append all the data from all three services:

<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){

	$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?ids=52723107@N00&lang=en-us&format=json&jsoncallback=?", function(data){
	  $.each(data.items, function(index, item){
		$("<img/>").attr("src", item.media.m).appendTo("#flickr")
		  .wrap("<a href='" + item.link + "'></a>");
	  });
	});
	
	$.getJSON('http://twitter.com/status/user_timeline/chriscoyier.json?count=10&callback=?', function(data){
		$.each(data, function(index, item){
			$('#twitter').append('<div class="tweet"><p>' + item.text.linkify() + '</p><p>' + relative_time(item.created_at) + '</p></div>');
		});
	
	});
	
	$.getJSON("http://www.scrnshots.com/users/chriscoyier/screenshots.json?callback=?", function(screenshots){
		$.each(screenshots, function(index, screenshot){
			$("#scrnshots").append("<a href='" + screenshot.url + "'><img src='" + screenshot.images.small + "' /></a>");
		});
	});

});
</script>

 

Cleaning Up Twitter

Two little problems with the “raw” data the Twitter API spits out.

  • Links come in “dead”. The full URL is there, but it’s just text, not a real anchor link.
  • The date comes in as an ugly timestamp, not nice human-readable text like “2 days ago”.

Two little javascript functions I dug up to deal with these problems.

Linkify:

String.prototype.linkify = function() {
  return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
    return m.link(m);
  });
};

relative_time:

function relative_time(time_value) {
  var values = time_value.split(" ");
  time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset() * 60);
  
  var r = '';
  if (delta < 60) {
	r = 'a minute ago';
  } else if(delta < 120) {
	r = 'couple of minutes ago';
  } else if(delta < (45*60)) {
	r = (parseInt(delta / 60)).toString() + ' minutes ago';
  } else if(delta < (90*60)) {
	r = 'an hour ago';
  } else if(delta < (24*60*60)) {
	r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
  } else if(delta < (48*60*60)) {
	r = '1 day ago';
  } else {
	r = (parseInt(delta / 86400)).toString() + ' days ago';
  }

So now instead of just putting “item.text” in your append statement, you can put “item.text.linkify()”. Also instead of putting “item.created_at” you can put “relative_time(item.created_at)”.

Thanks

Functions for “linkify” and “relative_time” from Ralph Whitbeck.

Thanks to Greg Bell for whipping the ScrnShots API into shape for me!

View Demo   Download Files