Year in Cats-3606 by Tom Royal on Flickr
Year in Cats-3407 by Tom Royal on Flickr
Year in Cats-3207 by Tom Royal on Flickr
Year in Cats-3125 by Tom Royal on Flickr
Year in Cats-3045 by Tom Royal on Flickr
Year in Cats-2790 by Tom Royal on Flickr
Year in Cats-2600 by Tom Royal on Flickr
Year in Cats-2500 by Tom Royal on Flickr
Year in Cats-2494 by Tom Royal on Flickr
Year in Cats-2249 by Tom Royal on Flickr

You're using a very old version of Internet Explorer which can't show the photos that should be in this box. Please consider upgrading to a newer version of IE or an alternative such as Firefox. Thanks.

How to: Read Flickr API JSON via jQuery

March 28th, 2012

I always prefer to read API data in XML, but there are times when that becomes problematic – especially due to cross domain access policies. If you're working on a single app it's possible to solve that by proxying the XML with a local PHP script, but if you're working with the browser only – in an HTML app, for example – that's no good. One way around is to use JSON.

Except that I have never really understood JSON.

So, using Flickr as an example, here's how to reach to the API, execute the API call, and parse the JSON results into something useful. It builds on this useful post at Webhole and assumes you know the basics of jQuery etc.

Step 1: Sort out the API URL

You'll need to know the API endpoint URL. I'm using the photosets.getPhotos call.

http://api.flickr.com/services/rest/?format=json&jsoncallback=?&api_key=YOURKEYHERE&photoset_id=YOURSETIDHERE&method=flickr.photosets.getPhotos&per_page=5

Note the inclusion of format=json&jsoncallback=?, which is needed. Also, I've limited the results to five just for testing's sake.

Build this URL in the usual way, and stash it in a variable called apiurl.

Step 2: Check the results

If you bung that URL in a browser, you should get something like the following:

jsonFlickrApi({
"photoset":{
"id":"72157627904918000",
"primary":"6244703830",
"owner":"40732557432@N01",
"ownername":"tomroyal",
"photo":[
{"id":"6243961525", "secret":"x", "server":"6091", "farm":7, "title":"Meiji Jingu Torii", "isprimary":"0"},
{"id":"6243946793", "secret":"x", "server":"6050", "farm":7, "title":"Sad Polar Bears", "isprimary":"0"},
{"id":"6243947391", "secret":"x", "server":"6229", "farm":7, "title":"Rainy Shinjuku", "isprimary":"0"},
{"id":"6244679360", "secret":"x", "server":"6170", "farm":7, "title":"Tokyo to Kyoto", "isprimary":"0"},
{"id":"6244162047", "secret":"x", "server":"6042", "farm":7, "title":"Hikari Shinkansen", "isprimary":"0"}
],
"page":1,
"per_page":"5",
"perpage":"5",
"pages":23,
"total":"112"},
"stat":"ok"})

So, in there you have a group of data called photoset containing load of value pairs (ownername = tomroyal, etc), and also an array containing another set of pairs per photo. I'll explain how to get one of the values, and to loop through the photo data.

Step 3: Document Ready

Add the following to your document.ready:

$('#button').click(function(){
$.getJSON(apiurl,function(json){
// do stuff
});
});

Obviously this function fires when somebody clicks the object with ID = button. The getJSON line fetches the API feed using the address we stored in the variable apiurl. Once that's fetched, we can process the results.

Step 4: Get your data

Now you'll need to add the bit that gets the data out of the pesky JSON. Replace the // do stuff line with:

$("#results").append('<p>"'+json.photoset.id+'"</p>');
$.each(json.photoset.photo,function(i,myresult){
$("#results").append('<p>"'+myresult.id+'"</p>');
});

To get a single value, we simply use json.photoset.variablehere – in this case json.photoset.id, or json.photoset.ownername.

To l0op through an array, use $.each. Our array is json.photoset.photo, so we loop through that, treating each entry as myresult. Values inside the array row can then be accessed with myresult.variablehere (eg, myresult.secret).

That's it. Easy once you know how.

Complete code:

<html>
<head><
script type="text/javascript">
var apiurl = "XXXXX"; // build your URL here
$(document).ready(function(){
$('#button').click(function(){
$.getJSON(apiurl,function(json){
$("#results").append('<p>"'+json.photoset.id+'"</p>');
$.each(json.photoset.photo,function(i,myresult){
$("#results").append('<p>"'+myresult.id+'"</p>');
});
});
});
});
</script>
</head>
<body>
<div id="button">button</div>
<div id="results"></div>
</body>
</html>

Republishing Tumblr via XML in PHP

April 10th, 2011

I love self-hosted WordPress and have used Perch recently, but sometimes you just want to knock up a blog page for someone or something quickly and easily. Last week I wanted to add a blog to the Tea and Kittens site and, while scanning around for options, found out that Tumblr has an amazing XML-based API.

This allows you to create a page that displays listed blog posts, or individual posts, from a Tumblr blog for display elsewhere, quickly and easily. It won't be suited for all projects, but it's a simple way to add a blog to just about any page. My code builds on some simple examples online, such as the excellent one here here.

There are two key limitations of this code:

  • The content for your blog will appear at http://yourblog.tumblr.com as well as at http://yoursite.com/blog.php
  • The code below only handles text-based posts. It could be easily expanded for Tumblr's other content types.

For an example of the finished blog page, see the Fluffington Post.

How to do it

First, set up a Tumbr blog at yournameorwhatever.tumblr.com. There's no need to register for an API or anything like that. Then create blog.php from this code:

<?php
$cpost = $_GET["post"]

// change this to the name of your Tumblr:

$tumblename = 'yournameorwhatever';

// Include all your top-of-page HTML and CSS here, ideally via a nice simple include

// check to see if viewing a post, or listing:
if (is_numeric($cpost)){

// blog.php is viewing a single post, so get it:
$request_url = 'http://' . $tumblename . '.tumblr.com/api/read?id=' . $cpost;
$xml = simplexml_load_file($request_url);

// check that you've got some valid post data
if($xml ===  FALSE){
echo '<p>Oh dear, epic fail. Click <a href="./blog.php">here</a> to go back to the index.</p>';
}
else {

// you have post data, so handle and display it:
foreach ($xml->posts->post as $post) {
$title = $post->{'regular-title'};
$body = $post->{'regular-body'};
$da2 = date("jS F Y",strtotime($post['date']));
$aname = $post['id'];
$alink = './blog.php?post=' . $post['id'];
$tlink = 'http://' . $tumblename . '.tumblr.com/' . $post['id'];
echo '<a name="'.$aname.'"><h2>'.$title.'</h2></a>';
echo '<p>'.$da2.'<p>';
echo '<p>'.$body.'<p>';
echo '<p></p>';
echo '<p>Posted on '.$da2.'. Permalink <a href="'.$alink.'">here</a>, or view on Tumblr <a href="'.$tlink.'">here</a>. Click <a href="./blog.php">here</a> for the index.</p>';
}
}
}
else {
// no individual post requested, so get the latest bunch from Tumblr
// pull from tumblr
$request_url = 'http://' . $tumblename . '.tumblr.com/api/read';
$xml = simplexml_load_file($request_url);
foreach ($xml->posts->post as $post) {
$title = $post->{'regular-title'};
$body = $post->{'regular-body'};
$da2 = date("jS F Y",strtotime($post['date']));
$aname = $post['id'];
$alink = './blog.php?post=' . $post['id'];
$tlink = 'http://' . $tumblename . '.tumblr.com/' . $post['id'];
echo '<a name="'.$aname.'" href="'.$alink.'"><h2>'.$title.'</h2></a>';
echo '<p>'.$da2.'<p>';
echo '<p>'.$body.'<p>';
echo '<p></p>';
echo '<p>Posted on '.$da2.'. Permalink <a href="'.$alink.'">here</a>, or view on Tumblr <a href="'.$tlink.'">here</a>.</p>';
}
}
?>

Change the fourth line so it reflects your Tumblr address, add some HTML tags and styling, and that's it. Enjoy!