How I built icant.co.uk – source code

After “my talk at FOWA in Cambridge”:http://www.slideshare.net/cheilmann/remixing-and-distribution-of-web-content-made-dead-easy yesterday I showed off that “http://icant.co.uk”:http://icant.co.uk is fully driven by YUI and YQL and maintained elsewhere. I’ve recorded a “screencast about this earlier”:http://developer.yahoo.net/blogs/theater/archives/2009/04/screencast_collating_distributed_information.html which is also “available for download as a M4V“:http://us.dl1.yimg.com/download.yahoo.com/dl/ydn/yqlscreencast2.m4v but hadn’t released the code yet.

So here goes – this is the PHP source of icant.co.uk (without the HTML which is more or less done with “YUI grids builder”:http://developer.yahoo.com/yui/grids/builder/


// get all the feeds to grab the data
$feeds = array(
  'http://feeds2.feedburner.com/wait-till-i/gwZf',
  'http://feeds.delicious.com/v2/rss/codepo8/myvideos?count=15',
  'http://feeds.delicious.com/v2/rss/codepo8/sandbox',
  'http://feeds.delicious.com/v2/rss/codepo8/icantarticles',
  'http://www.slideshare.net/rss/user/cheilmann'
);

// assemble the YQL statement
$yql = 'select meta.views,content.thumbnail,content.description,title,'.
       'link,description from rss where url in ';
$yql .= "('" . join($feeds,"','") . "')";

// assemble the request url
$root = 'http://query.yahooapis.com/v1/public/yql?q=';
$url = $root . urlencode($yql) . '&format=json';

// get the feeds and populate the data to echo out in the HTML
$feeds = renderFeeds($url);
$blog = $feeds['blog'];
$videos = $feeds['videos'];
$articles = $feeds['articles'];
$presentations = $feeds['slides'];

// this function loads all the feeds and turns them into HTML
function renderFeeds($url){

  // grab the content from YQL via cURL
  $c = getStuff($url);

  // as the content comes back as JSON, turn it into PHP objects
  $x = json_decode($c);

  // reset counter for videos and presentations
  $count = 0;
  $vidcount = 0;

  // start new array to return
  $out = array();

  // loop over YQL results, if they exist.
  if($x->query->results->item){
    foreach($x->query->results->item as $i){

      // if the link comes from the blog, add to the blog HTML
      if(strstr($i->link,'wait-till-i')){
        $out['blog'] .= '<li><h3><a href="' . $i->link . '">' . $i->title .
                        '</a></h3></li>';
      }

      // if the description contains an embed code, add to videos
      // (I use delicious for video bookmarks and add the embed code 
      // as a description, check here:
      //         http://feeds.delicious.com/v2/rss/codepo8/myvideos)
      if(strstr($i->description,'&lt;embed') && $vidcount < 4){
        $out['videos'] .= '<li><h3><a href="' . $i->link . '">' . $i->title .
                          '</a></h3><p>' . html_entity_decode($i->description) . 
                          '</p></li>';
        $vidcount++;
      }
      // for interviews and articles, add to the articles section 
      if(strstr($i->title,'Interview') ||
         strstr($i->title,'Article:')){
        $out['articles'].= '<li><h4><a href="' .$i->link . '">' .$i->title .
                           '</a></h4><p>'.html_entity_decode($i->description). 
                           '</p></li>';
      }

      // for slideshare, add to slides element.
      if(strstr($i->link,'slideshare') && $count < 4){
        $out['slides'] .= '<li><h3><a href="' . $i->link . '">' . $i->title . 
                          '</a></h3><p><a href="' . $i->link . 
                          '"><img src="' . $i->content->thumbnail->url .
                          '"></a>' . $i->content->description->content . 
                          '</p></li>';
        $count++;
      }
    }
  }
  // return back the array :)
  return $out;
}

// Grab the conference agenda from my blog
$yql = 'select * from html where url='.
       '"http://wait-till-i.com/talks-and-conference-participation/"'.
       ' and xpath="//ul" limit 1';
$travels = renderHTML($root.urlencode($yql).'&format=xml&diagnostics=false');
// btw, diagnostics=false means YQL doesn't send a diagnostics part

// grab the books from my blog
$yql = 'select * from html where url='.
       '"http://wait-till-i.com/books/"'.
       ' and xpath="//div[@class=\'entry\']"';
$books = renderHTML($root.urlencode($yql).'&format=xml&diagnostics=false');

// this is a quick and dirty solution for the HTML output 
function renderHTML($url){
  // pull the information from YQL
  $c = getStuff($url);
  // check that something came back
  if(strstr($c,'<')){
    // remove all the XML parts
    $c = preg_replace("/.*<results>|<\/results>.*/",'',$c);
    $c = preg_replace("/<\?xml version=\"1\.0\"".
                      " encoding=\"UTF-8\"\?>/",'',$c);
    // remove all comments
    $c = preg_replace("//",'',$c);
  }
  // send it back
  return $c;
}

// a simple cURL function to get information
function getstuff($url){
  $curl_handle = curl_init();
  curl_setopt($curl_handle, CURLOPT_URL, $url);
  curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
  curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
  $buffer = curl_exec($curl_handle);
  curl_close($curl_handle);
  if (empty($buffer)){
    return 'Error retrieving data, please try later.';
  } else {
    return $buffer;
  }
}

Tags: , , , , ,

2 Responses to “How I built icant.co.uk – source code”

  1. Rob Winters Says:

    Hi Chris
    Thanks for sharing this, its all great stuff.

    I’m very new to PHP but I’ve had a good old play with this and even though I’m only a front end dude I’ve managed to get something similar working for me using your example above as a guide. Woohoo, very satisfying.

    On my local environment it works fine but live I get this error “Call to undefined function json_decode()” I think its because my live sever runs php 5.1.4 and json_decode() needs 5.2.X

    I’ve googled high and low but haven’t found anything that works for me. Any ideas on how I get around this?

    Again thanks for sharing it’s greatly appreciated.

  2. Rob Winters Says:

    All sorted. Well kind of. I cheated and got the XML instead. Here is my first little step into the world of YQL.

    Cheers
    Rob

Wait till I come! is the blog of Christian Heilmann , a developer evangelist living and working in London, England. Download vcard.

Feed me, Seymour: Entries (RSS) and Comments (RSS).