SimplePie & jQuery Flickr Photostream
If you want to display a number of photos on your website, jQuery Infinite Carousel is a very good option. This carousel works really well when you have a list of images on your page, but it threw up a number of problems when calling images dynamically on page load (I.e. your latest Flickr Photostream or set).
I found the scroller worked perfectly in Firefox 3.5, but Safari, Chrome and IE all had issues with scrolling the carousel forward and backwards. Without going into too much detail it looks like a DOM issue with the dynamic images not loading correctly.
I fixed this problem by using SimplePie to parse the Flickr feed, cache the images into a folder, and then dynamically pull the images into the HTML on page load.
I also setup a cronjob to automatically update the cache on a weekly basis (I don’t update my Flickr account anymore than that). This fixed the issue with the carousel and sped up page loads because the images are called from a cache folder rather than being downloaded each time from the Flickr API. It’s important that the cronjob is in place; otherwise SimplePie will parse the Flickr feed on each load (or however often you set the cache to expire). I covered this in a previous post regarding parsing of Google Reader shared items.
See a demo of the SimplePie and jQuery Infinite Carousel on this site »
How to do it
1. Download carousel.js from here and upload to a folder on your server (I.e. www.yoursite.com/js/carousel.js)
2. Download SimplePie here and follow the instructions for installing SimplePie on your server.
3. Create a PHP page as follows (I’ve commented within the code with some specific instructions) and upload it to your server:
<?php
// Change the path below to the location of simplepie.inc on your server
require '/home/username/public_html/simplepie.inc';
// Change the URL below to the feed URL for your Flickr Photostream or a specific set
$url = 'http://api.flickr.com/services/feeds/photoset.gne?set=72157621912224879&nsid=39505387@N02&lang=en-us';
$feed = new SimplePie();
$feed->set_feed_url($url);
// This allows the cronjob to handle image caching rather than slow page loads as SimplePie parses the feed each time
$feed->set_cache_duration(999999999);
$feed->set_timeout(-1);
// Change the location below to where you have placed your cache folder and CHMOD the cache folder to 755 or 777
$feed->set_cache_location($_SERVER['DOCUMENT_ROOT'] . '/folder/cache');
$feed->init();
$feed->handle_content_type();
function image_from_description($data) {
preg_match_all('/<img src="([^"]*)"([^>]*)>/i', $data, $matches);
return $matches[1][0];
}
function select_image($img, $size) {
$img = explode('/', $img);
$filename = array_pop($img);
$s = array(
'_s.', // square
'_t.', // thumb
'_m.', // small
'.', // medium
'_b.' // large
);
$img[] = preg_replace('/(_(s|t|m|b))?\./i', $s[$size], $filename);
return implode('/', $img);
}
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SimplePie and Infinite Carousel Example</title>
<script type="text/css">
.infiniteCarousel {
width:533px;
position:relative
}
.infiniteCarousel #flickrgallery {
width:465px; /* .infiniteCarousel width - (.wrapper margin-left + .wrapper margin-right) */
overflow:auto;
height:110px;
margin:0 34px;
position:absolute;
top:0
}
.infiniteCarousel ul a img {
border:5px solid #fff;
-moz-border-radius:5px;
-webkit-border-radius:5px;
}
.infiniteCarousel #flickrgallery ul {
width:840px; /* single item * n */
list-style-image:none;
list-style-position:outside;
list-style-type:none;
margin:0;
padding:0;
position:absolute;
top:0
}
.infiniteCarousel ul li {
display:block;
float:left;
padding:0 10px 0 0;
height:85px;
width:85px
}
.infiniteCarousel ul li img {
-webkit-transition:border-color 400ms;
}
.infiniteCarousel ul:hover li img {
border-color:#fff
}
.infiniteCarousel ul:hover li:hover img {
border-color:#fff
}
.infiniteCarousel ul li a img {
display:block
}
.infiniteCarousel .arrowflickr {
display:block;
height:85px;
width:30px;
/* Add images for the forward and back arrows and use negative text-indent to hide the arrow characters */
/*background:transparent url("http://www.yourwebsite.com/images/arrows.png") no-repeat;
text-indent:-9999px;*/
position:absolute;
top:0;
cursor:pointer;
outline:0;
border:0
}
.infiniteCarousel .forward {
background-position:-830px -1020px;
right:0
}
.infiniteCarousel .back {
background-position:-830px -1128px;
left:0
}
.infiniteCarousel .forward:hover,
.infiniteCarousel .back:hover {
background-color:#fff
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script src="http://www.yourwebsite.com/js/carousel.js" type="text/javascript"></script>
<script type="text/javascript">$(document).ready(function(){$('.infiniteCarousel').infiniteCarousel();});</script>
</head>
<body>
<h1>SimplePie and Infinite Carousel Example</h1>
<div class="infiniteCarousel">
<div id="flickrgallery">
<ul>
<?php foreach ($feed->get_items() as $item): ?>
<li><?php
if ($enclosure = $item->get_enclosure()) {
$img = image_from_description($item->get_description());
/* Choose image size you want to link to (full_url) and display in carousel (thumb_url)
$full_url = select_image($img, 3);
$thumb_url = select_image($img, 0);
echo '<a href="' . $full_url . '" title="' . $enclosure->get_title() . '"><img src="' . $thumb_url . '" alt=" " /></a>'."\n";
}
?></li>
<?php endforeach; ?>
</ul>
</div>
</div>
</body>
</html>
4. Create the following cronjob PHP file which will tell SimplePie to parse the feed at the time(s) you specify (For a discussion of cronjob see previous post):
<?php
// Change the path below to the location of simplepie.inc on your server
require '/home/folder/public_html/simplepie.inc';
// Change the URL below to the feed URL for your Flickr Photostream or a specific set
$url = 'http://api.flickr.com/services/feeds/photoset.gne?set=72157621912224879&nsid=39505387@N02&lang=en-us';
$feed = new SimplePie();
$feed->set_feed_url($url);
// Tells SimplePie to update cache every time PHP file is loaded. Cronjob handles specific times that this page is loaded
$feed->set_cache_duration(0);
$feed->set_timeout(5);
// Change the location below to where you have placed your cache folder and CHMOD the cache folder to 755 or 777
$feed->set_cache_location($_SERVER['DOCUMENT_ROOT'] . '/folder/cache');
$feed->init();
$feed->handle_content_type();
function image_from_description($data) {
preg_match_all('/<img src="([^"]*)"([^>]*)>/i', $data, $matches);
return $matches[1][0];
}
function select_image($img, $size) {
$img = explode('/', $img);
$filename = array_pop($img);
$s = array(
'_s.', // square
'_t.', // thumb
'_m.', // small
'.', // medium
'_b.' // large
);
$img[] = preg_replace('/(_(s|t|m|b))?\./i', $s[$size], $filename);
return implode('/', $img);
}
?>
5. Upload PHP file to your server and setup a cronjob to automatically load the file at set time(s).