Flickr

www.flickr.com

Monday, January 24, 2011

Photoblog with Flickr API, PHP and Movable Type

Flickr comes with basic tools to publish content to a photoblog such as one powered by Movable Type. But with a bit of knowledge of PHP and the Flickr API, extra Flickr photo details can be added to make the posts more interesting. I will show you how to add extra Flickr information such as tags, image source URL, location information, favourites and comment information that is not provided through Flickr's blog feature. This guide assumes knowledge of PHP and access to a Movable Type version 2.6x Weblog installation.


Flickr API Key

Firstly you need to apply for a Flickr API key.
Flickr API Key

Follow the prompts and you should get a page with the key and secret. Call the Flickr App any name you like.


Photoblog Configuration

Login to your Movable Type site. Click on Weblog Config and click "Preferences / Configuration". Navigate to "File extensions..." and enter "php".

movable type


Photoblog Templates and PHP code

Go to the templates menu and select "Main Index Template".

We then need to insert the code which controls the Flickr API calls that request the photo information for our post.

Before continuing, I will first explain briefly the functions that will fetch and format the photo information from Flickr.

function getFlickrData(url) - This function gets the information given the URL of the photo in Flickr. This example gets the tags, the original source url (as Flickr only gives the medium and small image url in the blog feature), favourites, date taken and number of comments into an array of string.

function printFlickrStats($flickrdata,$url) - This function prints the number of comments and favourites of the photo from the array that was generated in function getFlickrData. Also gets the URL as I want a hotlink for the URL.

function printFlickrInfo($flickrdata) - This function prints the date, tags and location information from the array generated in function getFlickrData.

function printFlickrImg($url) - This function gets the URL data from getFlickrData and generates the URL of the large image

Here's the PHP code of the above functions. I won't go into specifics of the code and it is a bit messy but does the purpose. You will need to edit the print functions to fit your template.

<?php

function getFlickrData($url)
{
$tagstring="";
$flickr_api_key="your api key";
$comp = explode("/",$url);
$photo_id=$comp[5];
$filepath="<MT archive path>/".$photo_id.".php";
$flickr_tags="";
$cache_life='86400';
if (file_exists($filepath) and (time() - filemtime($filepath) <= $cache_life)) {
$filecntnt=file_get_contents($filepath);
$cntnt=explode("!",$filecntnt);
$faves=$cntnt[0];//get the faves
$comments=$cntnt[1];//get the comments
$url=$cntnt[2];// get url
$info=$cntnt[3];
for ($i=4; $i<sizeof($cntnt); ++$i)
{
$info=$info."!".$cntnt[$i];
}
$filecntnt=$info;
}
else {
$flickrrawoutput = file_get_contents("http://flickr.com/services/rest/?method=flickr.photos.getInfo&photo_id=$photo_id&api_key=$flickr_api_key&format=php_serial");
$flickroutput=unserialize($flickrrawoutput);
$status=$flickroutput['stat'];
if ($status !='fail') {
$flickr_tags = $flickroutput['photo']['tags']['tag'];
$flickr_dates = $flickroutput['photo']['dates'][posted];
$posted_date = date("jS F Y", $flickr_dates);
$locality= $flickroutput['photo']['location']['locality']['_content'];
$county= $flickroutput['photo']['location']['county']['_content'];
$region= $flickroutput['photo']['location']['region']['_content'];
$country= $flickroutput['photo']['location']['country']['_content'];
$comments=$flickroutput['photo']['comments']['_content'];
// get farm, server, photo id and secret (original)
$url=$flickroutput['photo']['farm'].".".$flickroutput['photo']['server'].".".$photo_id.".".$flickroutput['photo']['originalsecret'];
}
foreach ($flickr_tags as $value) {
if ($tagstring=="") {
$tagstring=$value[raw];
}
else {
$tagstring = $tagstring.", ".$value[raw];
}
}
$filecntnt=$tagstring."!".$posted_date."!".$locality."!".$county."!".$region."!".$country."!";
//get the number of favourites
$flickrrawoutput = file_get_contents("http://flickr.com/services/rest/?method=flickr.photos.getFavorites&photo_id=$photo_id&api_key=$flickr_api_key&format=php_serial");
$flickroutput=unserialize($flickrrawoutput);
$status=$flickroutput['stat'];
if ($status !='fail') {
$faves = $flickroutput['photo']['total'];
}
file_put_contents($filepath,$faves."!".$comments."!".$url."!".$filecntnt);
}
$photoinfo[0]=$faves."!".$comments;
$photoinfo[1]=$filecntnt;
$photoinfo[2]=$url;
return $photoinfo;
}

function printFlickrStats($datastr,$photourl)
{
$dataarr=explode("!",$datastr);
print "<li>Faves: ".$dataarr[0]."</li>";
print "<li>Comments: ".$dataarr[1]."</li>";
print "<li><a href=\"".$photourl."\">Flickr Page</a></li>";
}

function printFlickrInfo($fdatastr)
{
$content=explode("!",$fdatastr);
print "<p>Tags:<br/>".$content[0]."</p>";
print "<p>Date Posted:<br/> ".$content[1]."</p>";
print "<p>Taken in:<br/> ".$content[2].", ".$content[3].", ".$content[4].", ".$content[5].".</p>";
}

function printFlickrImg($urldata)
{
$urlarr=explode(".",$urldata);
$url="http://farm".$urlarr[0].".static.flickr.com/".$urlarr[1]."/".$urlarr[2]."_".$urlarr[3]."_o.jpg";
list($width, $height, $type, $attr) = getimagesize($url);
if ($width > $height) {
print "<img src=\"".$url."\" width=\"850\">";
} else {
print "<img src=\"".$url."\" height=\"850\">";
}
}

?>

Note that I also store the Flickr data for one day which is determined by variable cache_life.

The functions are placed before the entry data is generated by Flickr. For example:

<body>
<div class="mainbox">
<!--
place the php code here
-->
<div class="left"></div>
<div class="middle">
<h1>sparkle</h1>
<ul>
<li class="home"><a href="/flickr.php"><span>Home</span></a></li>
<li class="about"><a href="/aboutflkr.html"><span>About</span></a></li>
<li class="flickr"><a href="/archivesflkr.php"><span>Archives</span></a></li>
</ul>
<div class="imagebox">
<div class="imageborder">
<!-- Begin flickr snippet -->
<$MTEntryBody$>
<!-- End flickr snippet -->
<ul>
<li class="info">
<?php
print "<a href=\"".$photourl."\"><span>flickr</span></a>";
?></li>
<li class="prev">
<a id="inline" href="#data"><span>info</span></a></li>
<li class="prev">
<MTIfEmpty expr="[MTEntryPrevious]1[/MTEntryPrevious]">
<b>&diams;</b>
</MTIfEmpty>
<MTEntryPrevious><a href="<$MTEntryLink$>"><span>&larr;</span></a>
</MTEntryPrevious></li>
<li class="next"><MTEntryNext><a href="<$MTEntryLink$>"><span>&rarr;</span></a></MTEntryNext>
<MTIfEmpty expr="[MTEntryNext]1[/MTEntryNext]">
<b>&diams;</b>
</MTIfEmpty>
</li>
</ul>
</div>
</MTEntries>
</div>
<div class="right"></div>
</div>
<div class="bottombox">
<div class="bleft"></div>
<div class="bottom"></div>
<div class="bright"></div>
</div>
</body>


Flickr Blog settings

Go to Your Account and select "Sharing and Extending".

Set up a new blog. In this case, I've set up a new Movable Type Blog. Instructions can be found here.


Flickr Blog settings

Then select "Layout" and pick any of the layouts displayed.

On next page, go to the bottom and press "Customise".

Flickr
Insert the following code into the box.


<?php
$photourl='{photo_url}';
$fdata=getFlickrData($photourl);
printFlickrImg($fdata[2]);
?>
</div>
<h2 class="caption">{photo_title}</h2>

<div style="display:none">
<div id="data">
<h2>{photo_title}</h2>
<div class="thumb">
<img src="{photo_src_t}">
<ul>
<?php
printFlickrStats($fdata[0],$photourl); // print the list
?>
</ul>
</div>
<?php
print "{description_raw}"; // could be null
print "<p>{photo_desc}</p>";
printFlickrInfo($fdata[1]);
?>
</div>
</div>


This will be the content for the <$MTEntryBody$> variable defined in Movable type. Note that it calls the top level functions mentioned.