jQuery Galleriffic gallery with Flickr feed

Friday, 8 January 2010


This post looks at how you can combine the great look and functionality of the Galleriffic jQuery photo gallery plugin with Flickr.



Flick has great functionality already for you to share and view your photos, but the one thing that it doesn't provide is custom styling. If you want to combine a particular Flick photo album within a web design or your own blog you can do so relatively easy with the use of Flickr's API and a bit of javascript. Today I will look at grabbing a Flickr feed using JSON and combine that with the fast and fantastic jQuery Galleriffic plugin.

You can view a working example of this here. You can download the code here.

The Galleriffic plugin is well styled out of the box, but can easily be customised and has all the features you would want: pagination, slideshow and nice transition effects. My main interest in this plugin is that it looks classy and works well with very little customisation.

I will do a simple example and you can do the rest to integrate it into you site or design. I'm going to base my example on Galleriffic's own example-2.html. Begin by downloading Gallerific and you will find all the examples in the root directory. Open up example-2.html and let's begin editing.

Start by removing all of the li elements except for the first one from the thumbs div, we will be using the remaining li element to clone later on. It should now look something like this:

<div id="thumbs" class="navigation">
    <ul class="thumbs noscript">
        <li>
            <a class="thumb" name="leaf" href="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg" title="Title #0">
                <img src="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg" alt="Title #0" />
            </a>
            <div class="caption">
                <div class="download">
                    <a href="http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg">Download Original</a>
                </div>
                <div class="image-title">Title #0</div>
                <div class="image-desc">Description</div>
                <div class="image-auth"></div>
            </div>
        </li>
    </ul>
</div>

I also added in the image-auth div so I can give some credit to the authors of the photos used in my example.

Next we are going to change the document ready function. I'm going to show you the whole thing so you know where I'm coming from. Have a scan over it first and then I will explain what's going on. This is located at the bottom of the page just before the closing body tag.

jQuery(document).ready(function($) {
    $.getJSON("http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&lang=en-us&format=json&jsoncallback=?", function(data){
            $.each(data.items, function(i,item){
                var newthumb = $("ul.thumbs").children("li:first").clone();
                var baseimg = item.media.m;
                
                var thumbimg = baseimg.replace("_m.jpg", "_s.jpg");
                $(newthumb).find("img").attr("src", thumbimg);
                
                var disimg = baseimg.replace("_m.jpg", ".jpg");
                $(newthumb).find(".thumb").attr("href", disimg);
                
                var lgeimg = baseimg.replace("_m.jpg", "_b.jpg");
                $(newthumb).find(".download").children("a").attr("href", lgeimg);
                
                var title = item.title;
                var description = item.description;
                
                var desc = $("<div />").append(description);
                if ($(desc).children().size() == 3) {
                    description = $(desc).children("p:last").html();
                } else {
                    description = "";
                }
                
                $(newthumb).find(".image-title").empty().html(title);
                $(newthumb).find(".image-desc").empty().html(description);
                $(newthumb).find(".image-auth").empty().html(item.author);
                
                $("ul.thumbs").append(newthumb);
            });    
            
            $("ul.thumbs").children("li:first").remove();
            
            // Initially set opacity on thumbs and add
            // additional styling for hover effect on thumbs
            var onMouseOutOpacity = 0.67;
            $('#thumbs ul.thumbs li').opacityrollover({
                mouseOutOpacity:   onMouseOutOpacity,
                mouseOverOpacity:  1.0,
                fadeSpeed:         'fast',
                exemptionSelector: '.selected'
            });
            
            // Initialize Advanced Galleriffic Gallery
            var gallery = $('#thumbs').galleriffic({
                delay:                     2500,
                numThumbs:                 12,
                preloadAhead:              10,
                enableTopPager:            true,
                enableBottomPager:         true,
                maxPagesToShow:            7,
                imageContainerSel:         '#slideshow',
                controlsContainerSel:      '#controls',
                captionContainerSel:       '#caption',
                loadingContainerSel:       '#loading',
                renderSSControls:          true,
                renderNavControls:         true,
                playLinkText:              'Play Slideshow',
                pauseLinkText:             'Pause Slideshow',
                prevLinkText:              '&lsaquo; Previous Photo',
                nextLinkText:              'Next Photo &rsaquo;',
                nextPageLinkText:          'Next &rsaquo;',
                prevPageLinkText:          '&lsaquo; Prev',
                enableHistory:             false,
                autoStart:                 false,
                syncTransitions:           true,
                defaultTransitionDuration: 900,
                onSlideChange:             function(prevIndex, nextIndex) {
                    // 'this' refers to the gallery, which is an extension of $('#thumbs')
                    this.find('ul.thumbs').children()
                        .eq(prevIndex).fadeTo('fast', onMouseOutOpacity).end()
                        .eq(nextIndex).fadeTo('fast', 1.0);
                },
                onPageTransitionOut:       function(callback) {
                    this.fadeTo('fast', 0.0, callback);
                },
                onPageTransitionIn:        function() {
                    this.fadeTo('fast', 1.0);
                }
            });                        
    });

    // We only want these styles applied when javascript is enabled
    $('div.navigation').css({'width' : '300px', 'float' : 'left'});
    $('div.content').css('display', 'block');
});

You will notice that almost everything is now wrapped inside the getJSON call. We need to ensure our pictures are loaded before we call the gallerific function.

The getJSON call is a simple call to the Flickr Feed API. Once you get the hang of what's going on in this tutorial your next step is getting a Flick developer key and using JSON, you can do all sorts of cool things with the Flickr API. For this post I'm just keeping it simple and we will just be using a Group feed.

The main part of the getJSON call is the URL: http://api.flickr.com/services/feeds/groups_pool.gne?id=32142572@N00&lang=en-us&format=json&jsoncallback=?. It calls the groups_pool services feed and simply passes in the group ID. This can be retrieved easily from any group by going to the group's Flickr page and clicking on the RSS link near the bottom left hand corner of the page. The RSS feed will have an URL similar to this: http://api.flickr.com/services/feeds/groups_discuss.gne?id=1239213@N21&lang=en-us&format=rss_200 and you just grab the value of the id variable.

The next thing we do is loop over the results:

$.each(data.items, function(i,item){
    var newthumb = $("ul.thumbs").children("li:first").clone();
    var baseimg = item.media.m;
    
    var thumbimg = baseimg.replace("_m.jpg", "_s.jpg");
    $(newthumb).find("img").attr("src", thumbimg);
    
    var disimg = baseimg.replace("_m.jpg", ".jpg");
    $(newthumb).find(".thumb").attr("href", disimg);
    
    var lgeimg = baseimg.replace("_m.jpg", "_b.jpg");
    $(newthumb).find(".download").children("a").attr("href", lgeimg);
    
    var title = item.title;
    var description = item.description;
    
    var desc = $("<div />").append(description);
    if ($(desc).children().size() == 3) {
        description = $(desc).children("p:last").html();
    } else {
        description = "";
    }
    
    $(newthumb).find(".image-title").empty().html(title);
    $(newthumb).find(".image-desc").empty().html(description);
    $(newthumb).find(".image-auth").empty().html(item.author);
    
    $("ul.thumbs").append(newthumb);
});    

data is returned in our callback function to the getJSON call. We then just loop over the data.items. If you want to look at what the feed looks like you can easily read it by going here and just replacing the Group id.

When we loop over each of the items we begin by cloning our first item in the .thumbs unordered list. We then get the baseimg which is the image source URL passed in from the feed. For each photo you upload to Flickr they have several formats but all have similar URLs so we are going to take advantage of this knowledge and we don't need to manipulate the image we retrieve from Flickr into different sizes e.g.

An image: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015.jpg
Image thumbnail: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_s.jpg
Big version: http://farm4.static.flickr.com/3261/2538183196_8baf9a8015_b.jpg

You can now see they are almost identical. So we are going to build these three image links from the one retrieved in the feed. Our three images are thumbimg, disimg and lgeimg; our thumbnail, display image and large image. We then use jQuery's selectors to replace these URLs in the cloned li element $(newthumb).

Next we want to get and set the title, description and author. The feed contains a preformated description with it's own thumbnail (who knows why, I guess for convenience). So we check the description HTML to see if it has three sections, if it does then a user description has been entered on Flickr and we grab it, otherwise just leave it blank:

var desc = $("<div />").append(description);
if ($(desc).children().size() == 3) {
    description = $(desc).children("p:last").html();
} else {
    description = "";
}

In the last step we insert the title, description and author and then append our cloned and updated li element:

$(newthumb).find(".image-title").empty().html(title);
$(newthumb).find(".image-desc").empty().html(description);
$(newthumb).find(".image-auth").empty().html(item.author);

$("ul.thumbs").append(newthumb);

Now that all the elements have been looped over and added we have one final thing to do before we proceed to build our gallery, we just need to remove our initial and no longer need first li element:

$("ul.thumbs").children("li:first").remove();

After this is done we just call the gallerific function as per the initial example and then we're all ready to go.

There's one small thing that I changed and that's the variable numThumbs which determines how many thumbs are displayed per page.

One last thing to note is that the Flickr feeds only provide 20 items. If you want to get more from your feeds you will need to get a developer key and use the Flickr API. The public feeds are deliberately restricted to avoid abuse.

Enjoy!
blog comments powered by Disqus