Wednesday, January 13, 2010

Bring Flickr to Your Website Using JSON and jQuery

Bring Flickr to Your Website Using JSON and jQuery

Bring Flickr to Your Website Using JSON and jQuery

Flickr is a great website for hosting and sharing your photos. If you are an amateur photographer who likes to share photos from your latest outdoor adventure, or even a professional photographer planning to market your work, then chances are you’ve at least heard of Flickr.  But what if you want to take your photo sharing to the next level by showcasing your photos on your personal website, but don’t want to deal with the hassle of updating your HTML each time you want to share a new photo? Fear not, because Flickr has developed an API especially for developers, and mixed with a little jQuery and JSON magic, you can update your website portfolio directly from your Flickr account.


What are jQuery and JSON?

Simply put, jQuery is Javascript. If you can write and understand  JavaScript, then jQuery is already a familiar concept to you. jQuery promotes interaction between JavaScript and HTML, which is accomplished by linking to a simple script in your HTML (the latest download is available from the jQuery website). Tutorials are also available on the jQuery website if you aren’t already familiar with jQuery, or if need to brush up on the key concepts. It is well worth your time to learn jQuery, as the amount of plugins and effects that can be accomplished through jQuery are growing daily, and it is a valuable resource for any developer looking to save time and expand website functionality.
JSON (JavaScript Object Notation) is a data interchange format that is easily parsed by computers and easy to read by humans. Written using a format that is readily-recognized by programmers, JSON allows data to be passed between websites through a request and a callback format. For example, if you run a website and want to retrieve a list of your Flickr photos for use on your own site, you would make a request to the Flickr API for a list of photos, and Flickr would respond with a callback, which would include a list of your photos, in JSON format.

Setting up Your Gallery

The best way to understand JSON and how you can send requests to Flickr using jQuery is through an example, so let’s jump into one right away. What we will be developing in this tutorial is a jQuery slideshow gallery that pulls photos from a Flickr gallery, and allows the user to switch between Flickr galleries through a drop-down menu.
Slideshow example
Slideshow tutorial example
The slide show gallery that we will be developing will be built using the work of User Friendly Thinking’s Open Source Flickr Photo Gallery using jQuery. For this example, you will need to download a few code snippets:
You will also need a Flickr API key, which is easy to obtain if you are developing your gallery for non-commercial purposes. To obtain your key, register for a Flickr account, then navigate to the Flickr Services page to apply for your key. Once the application process is completed, you will be provided with your API key (which you should copy and paste in a new document for future reference). Once your Flickr account is established, you should upload some photos to your gallery and organize these photos into Photo sets (albums) before integrating the gallery into your website. A quick tutorial on how to organize your photos into Photo sets is available here.
To set up your gallery for use on your website, use the implementation process as outlined in the open source Flickr example. This will provide you with the basic gallery, which enables you to show one Photoset per implementation.
But what if you want to show multiple Photosets within one gallery? In this case, you would need to retrieve a list of Photo sets that have already been created under your Flickr account. This is where JSON and a little jQuery tweaking come into play.

Using JSON

JSON provides a method of establishing communication between the application you have just set up on your website, and the Flickr API on the Flickr website. The Flickr request is developed by building a URL in the format of:
http://api.flickr.com/services/rest/?
All requests  to Flickr begin with this basic URL. What you append to this URL, however, depends on what information you would like to retrieve from the API. To determine what parameters to append to your URL, you will need to refer to the Flickr API Documentation. The right column of the documentation includes the API methods you will be using to communicate with the API. Keep in mind, however, that you can only use one method per request.
In our example, we want to request a list of Photosets that have been created under your Flickr account. So in the API documentation, we look under the “photo sets” heading for a list of methods we can use to access our Photosets. Since we need to retrieve a list of Photosets that are available, we will want to use the flickr.photosets.getList method. Click the link for this method, and we are provided with the arguments that we need to provide in order for this method to properly retrieve our list of photo sets. In this method, the two arguments are api_key for the Flickr account, and the user_id, which is the NSID of the user requesting the list (by the way, you can determine your NSID by logging into your Flickr account and navigating to this page. Your NSID is provided beneath the “Your user ID:” heading in the right column).
Now that we know what method and arguments we need in order to access our Photoset list, let’s continue to build our URL. Begin by specifying which method you will be using:
http://api.flickr.com/services/rest/?&method=flickr.photosets.getList
You will then want to append your two arguments, the api_key and the user_id:
http://api.flickr.com/services/rest/?&method=flickr.photosets.getList
&api_key=yourAPIKey&user_id=yourUserID
(Keep in mind that you will want to replace the values for api_key and user_id with your actual values).
Once you have built your URL, you can enter it into your browser and the request will return the callback data. However, the information presented will be returned in XML format.
XML Format
Correct data, but not the format we're looking for
XML is the default callback format, so in order to retrieve our request in JSON, we need to append one more parameter to our URL in order to specify that we want to receive our callback in JSON format:
http://api.flickr.com/services/rest/?&method=flickr.photosets.getList
&api_key=yourAPIKey&user_id=yourUserID&format=json&jsoncallback=?
Now if you enter this URL in your browser, you will see that the data is relayed in the JSON format.
JSON Format
JSON format!

Retrieving Photosets using jQuery

Now that we have built our request URL, we can retrieve our list of Photosets using jQuery. Luckily for us,  jQuery includes a built-in method for making JSON requests, namely jQuery.getJSON(url,data,callback). We have already built the URL, the first argument of the getJSON method, so we can begin to develop the rest of our getJSON function.
Before the $(document).ready line in your jQuery, add the following two Array variables, as we will need them later to store information about our Photosets:
var ids = new Array();
var titles = new Array();
Within the $(document).ready script, add the following code:
$(document).ready(function(){
$.getJSON("http://api.flickr.com/services/rest/?
&method=flickr.photosets.getList
&api_key=yourAPIKey&user_id=yourUserID
&format=json&jsoncallback=?",
});
});
The second argument of our getJSON method comes in the form of a function that will help us parse the JSON data that we receive.  Before we develop our function, however, we need to understand how to read the data that is sent back to us in JSON format. Here is an example of JSON-formatted data that we might receive when we make our API request:
jsonFlickrApi({"photosets":{"photoset":[{"id":"72157622889773773",
"primary":"4185579408","secret":"31db7024d6", "server":"2671", "farm":3,
"photos":"1", "videos":0,"title":{"_content":"Sample 2"},
"description":{"_content":""}},{"id":"72157622875855857",
"primary":"4184819047", "secret":"c913dd1d21",
"server":"2660", "farm":3, "photos":"2", "videos":0,
"title":{"_content":"Sample 1"},
"description":{"_content":""}}]}, "stat":"ok"})
On its own, the returned data is difficult to comprehend. But if we break down the data line-by-line, what has been returned to us starts to make a little more sense:
JSON Callback
Organizing the returned data in this manner allows us to see just what data has been returned in our callback. We can see that the data has been returned to us in an array, which in this example consists of two elements (as there are two Photosets in this example gallery, titled “Sample 1″ and “Sample 2″). Also, traversing the arrays shows us how we can access each data element that we are looking to use. For this example, we will need to know the ID of each element, and each title. Therefore, we would access the ID and title of the first Photoset the following way:
data.photosets.photoset.id[0]
data.photosets.photoset.title._content[0]
This is a handy reference point if you want to access just one Photoset, but in this tutorial, we are looking to retrieve all Photosets associated with a Flickr account. Doing so will require us to loop through all of the Photosets, storing all Photoset IDs and titles as we loop. Here is where we will construct our data function, which acts as the second argument on our getJSON function:
$(document).ready(function(){
$.getJSON("http://api.flickr.com/services/rest/?&method=flickr.photosets.getList
&api_key=yourAPIKey&user_id=5yourUserID
&format=json&jsoncallback=?",
function(data){
var photosetID = "";
var title = "";
$.each(data.photosets.photoset, function(i,set){
photosetID = set.id;
title = set.title._content;
ids.push(photosetID);
titles.push(title);
});
});
});
Here, we use jQuery’s each() loop to iterate through all Photosets. As we loop, we grab the ID and title of each Photoset, which we add to the “ids” and “titles” arrays we created earlier. Once we have looped through each of our Photosets, we will have two arrays consisting of all Photoset IDs and titles associated with our Flickr account.

Creating a Drop-Down Menu of Photosets


Now that we have retrieved all Photoset data and have built our ID and title arrays, it is time to construct a drop-down menu that will allow users to select which album he/she wants to show in the jQuery slideshow player. Placement of this menu is up to you, but I prefer to place the drop-down directly above the slideshow player. To start, create an empty “select” menu in your HTML titled “Galleries.” Also, be sure to add an “onchange” event handler to your drop-down:
<label>Please select a Gallery from the drop-down menu to view.</label>
<form action="" method="get" name="choose_gallery" id="choose_gallery">
<select name="Galleries" id="Galleries" onchange="showGallery();"></select>
</form>
We now have a drop-down menu where we can list all of the Photosets associated with our account.  Our next task is to add the Photosets from our arrays to our drop-down menu. Directly after the getJSON function, add the following code:
for(i=0; i<ids.length;i++){
var option = new Option(titles[i],ids[i]);
var dropDown = document.getElementById("Galleries");
dropDown.options[i] = option;
}
This “for” loop will add a new option to our drop-down for each Photoset. The Photoset’s ID will become the option’s value, and the title will become the option’s text.
We now need to change one value in our flickrGallery() function that we added at the beginning of the tutorial. In my gallery, I wanted to assure that the first gallery listed in my drop-down menu was the default gallery being displayed in the slideshow. To make this happen in your gallery, simply change the value for photosetID to the first ID in “ids” array:
photosetID: ids[0],
Our final step is to build the functionality for our “onchange” event function, showGallery(). I placed this function outside of the $(document).ready script, directly below the array variables:
function showGallery(){
var sel = document.getElementById("Galleries");
var selectedID = sel.options[sel.selectedIndex].value;
$(".largeImageWrap").each(function(i){
$(this).remove()
});
$(".sliderGallery_Wrap").each(function(i){
$(this).remove()
});
$('#flickrTest').flickrGallery({
galleryHeight : 'auto',
useFlickr: 'true',
useFlickrLargeSize: 'true',
useHoverIntent: 'true',
flickrAPIKey: 'yourAPIKey',
photosetID: selectedID,
useLightBox: 'true',
per_page: 50
});
}
The showGallery() function is triggered when a user selects a gallery from the drop-down menu. This function loads the selected Photoset into the slideshow player, effectively allowing the user to choose between Photosets while using one player. First, we need to discover which Photoset has been chosen in the drop-down. Once we know this, we switch the current photosetID to the selected ID. Note that in my case, the “sliderGallery_Wrap” and “largeImageWrap” classes were preventing the slideshow player from resizing appropriately, and removing them had no effect on how the player appeared and functioned.

Tying it all Together

Here is how my final code looked after all was said and done. Yours may differ slightly, depending on what size and display options you selected for your slideshow:
Javascript:
<script type="text/javascript">
var ids = new Array();
var titles = new Array();

function showGallery(){
var sel = document.getElementById("Galleries");
var selectedID = sel.options[sel.selectedIndex].value;
$(".largeImageWrap").each(function(i){
$(this).remove()
});
$(".sliderGallery_Wrap").each(function(i){
$(this).remove()
});
$('#flickrTest').flickrGallery({
galleryHeight : 'auto',
useFlickr: 'true',
useFlickrLargeSize: 'true',
useHoverIntent: 'true',
flickrAPIKey: 'yourAPIKey',
photosetID: selectedID,
useLightBox: 'true',
per_page: 50
});
}
$().ready(function(){
$.getJSON("http://api.flickr.com/services/rest/?&method=flickr.photosets.getList
&api_key=yourAPIKey&user_id=yourUserID&format=json&jsoncallback=?",
function(data){
var photosetID = "";
var title = "";
$.each(data.photosets.photoset, function(i,set){
photosetID = set.id;
title = set.title._content;
ids.push(photosetID);
titles.push(title);
});
for(i=0; i<ids.length;i++){
var option = new Option(titles[i],ids[i]);
var dropDown = document.getElementById("Galleries");
dropDown.options[i] = option;
}

$('#flickrTest').flickrGallery({
galleryHeight : 'auto',
useFlickr: 'true',
useFlickrLargeSize: 'true',
useHoverIntent: 'true',
flickrAPIKey: 'a22b1a90b000578e1854ebdb3a3b5ba7',
photosetID: ids[0],
useLightBox: 'true',
per_page: 50
});
});
});
</script>
HTML:
<label>Please select a Gallery from the drop-down menu to view.</label>
 <form action="" method="get" name="choose_gallery" id="choose_gallery">
<select name="Galleries" id="Galleries" onchange="showGallery();"></select>
</form>
<div id="flickrTest"></div>