Friday, January 11, 2013

Build a Simple Yahoo! Answers API Webapp with PHP

Build a Simple Yahoo! Answers API Webapp with PHP

The open Yahoo! API is a great resource to work with. There is plenty of documentation for web developers, along with live demos and examples. What makes the application so interesting is how Yahoo! manages so many different online services. Along with their search engine there is also Yahoo! news, maps, weather, and so much more.
For this tutorial I’d like to focus on the Yahoo! Answers API. We will be creating a simple webapp that pulls all recently answered questions from a select few categories. The API delivers results via XML or JSON, so we have the option to build with any backend programming language. Although for this guide I’ll stick to PHP since it’s the most commonly understood backend language.
Simple Yahoo! Answers API tutorial with PHP
Live DemoDownload Source Code

Register a New Application

To get going we first need a new developer API key. This is required so that Yahoo! can manage requests onto the network. Also so that developers can’t just make anonymous requests pulling massive amounts of bandwidth.
You’ll need to visit this new projects page and sign into your Yahoo! account. From there you will be asked some very basic questions about your application – doesn’t matter what you fill in as long as it makes sense. After completion you’ll be presented with an API ID that we’ll need on the backend PHP server-side.

Building the Document

Start out by creating a new page index.html which will hold our core page structure. I’ve included a reference to the most recent jQuery library along with an external script.js file. This will hold our Ajax calls once the document is finished.
Below is my exact code from the index file. You’ll notice that I’m including a few sample categories with IDs related to their Yahoo! ID.
<!doctype html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Yahoo! Answers Webapp - Popular Questions</title>
  <meta name="author" content="Jake Rocheleau">
  <link rel="stylesheet" type="text/css" href="style.css">
  <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Lemon">
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
  <script type="text/javascript" src="script.js"></script>
<!--[if lt IE 9]>
  <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>

<body>
  <div id="w">
    <h1>Select a Y! Answers Category</h1>
  
    <nav>
      <a href="#" id="396545444">Politics & Government</a>
      <a href="#" id="396545660">Computers & Internet</a>
      <a href="#" id="396545013">Business & Finance</a>
      <a href="#" id="396545122">Science & Mathematics</a>
      <a href="#" id="396545015">Education & Reference</a>
    </nav>
  
    <div id="content"></div>
  </div>
</body>
</html>
To gather some different IDs just hit the browse categories page and click on some of the different topics. In the new URL you’ll notice a variable appended to the end like ?sid=whatever. That long string of numbers is the unique ID for that category, and we can use that with the API to pull questions recently answered by users.

The PHP Backend

Before we connect into the Ajax/JavaScript let’s create the API data inside a PHP file named ajax.php. The top portion of my script contains a set of static variables which we need for specific API functionality.
$theid = $_POST['catid'];
$cats = array();
$cats['politics']  = "396545444";
$cats['internet']  = "396545660";
$cats['business']  = "396545013";
$cats['science']   = "396545122";
$cats['education'] = "396545015";

$appid = "YOURAPIKEYHERE";
$url = "http://answers.yahooapis.com/AnswersService/V1/getByCategory?appid=".$appid;
 
$apiurl = $url."&category_id=".$theid."&type=resolved&output=json&results=15";
The first variable $theid will be passed into the script from Ajax. This will be a unique category ID which is passed whenever the user clicks on a new category link. Then I’ve also setup an array of these categories so we know which ID number correlates to which category.
Now inside $appid you should replace that string with your own API key. It should be a very long sequence of numbers, letters, and possibly some dashes or other miscellaneous punctuation. The url contains the first piece to our API call along with this key appended onto the string. $apiurl concatenates this along with some new data based on the unique category ID passed in via Ajax.
You can change some of these attributes if you’d like to mess around with different results. However the response type should always be JSON because it’s much easier to manage than XML or direct PHP code.

Looping through Response Data

For the Ajax response to work properly with PHP we need to output all this data into plain HTML format and append this onto the page. You should notice in my index.html file there is a div with the ID #content that is totally empty. This will be our container for all the new data.
$i = 0;
 
// setup our data array
$dataobject = json_decode(file_get_contents($apiurl));
We first create a counter variable $i set to 0. This should be a unique integer which increases every time we loop through a new row of results. This helps us determine odd/even rows so we can apply alternating colors.
Also I’m using the PHP function json_decode() for updating this string of JSON data into an object collection. You’ll notice inside I’m also calling a function file_get_contents() – this is necessary to read the original JSON response from Yahoo!’s remote server. There are other libraries with this same functionality but I find PHP’s default method to be quicker & easier.
// begin output loop
foreach($dataobject->all->questions as $question) {
  $timestamp = $question->Timestamp;
  $dd = date("F d, Y", $timestamp);
  
  echo '<div class="qbox'.(($i = !$i)? ' odd':'').'">'."\r\n";
  echo '<h2><a href="'.$question->Link.'" target="_blank">'.$question->Subject.'</a></h2>'."\r\n";
  echo '<p>Posted '.$dd.' - Total answers: '.$question->NumAnswers.'</p>'."\r\n";
  echo '<p>Link URL: <a href="'.$question->Link.'" target="_blank">'.$question->Link.'</a></p>'."\r\n";
  echo '</div>'."\n\n\n";
 
  $i++;
}

die();
I’m using a really simple foreach() loop to go through the question object and output similar HTML. Each question is contained inside a div with the class .qbox and possibly an alternating class of .odd. The rows are colored with different backgrounds so you can scroll through results much easier. The final die() function is helpful to let Ajax know our script has finished running. It will save response times when calling the same script hundreds of times daily.

Connecting into jQuery/Ajax

Even if you don’t totally follow the PHP code don’t worry! API results are difficult to jump right into, but the concepts are still easy enough if you have time for research. For now let’s examine the final piece to this puzzle which is connecting into JavaScript calls.
$(document).ready(function(){
 
  $("nav a").on("click", function(e){
    e.preventDefault();
  
    var clickid = $(this).attr("id");
    var content = "#content";
I’m first placing an event handler whenever a user clicks any anchor links inside the nav element. We first stop the default href value from loading, then setup a couple variables which point to specific containers on the page.
    if($(this).hasClass("sel")) {
      // do nothing since we already have this selected
    } else {
      // change to display a new content container
      $("a.sel").removeClass("sel");
      $(this).addClass("sel");
   
      $(content).html("<center><img src=\"images/loader.gif\" alt=\"loading...\"></center>");
   
      $.ajax({
        type: "POST",
        url: "ajax.php",
        data: "catid="+clickid,
        dataType: "html",
        success: function(html) {
          $(content).html(html);
        }
      });
    }
  }); // end .on() click event handler
}); // end DOM ready()
If the current link has a class of .sel then we know it’s already been clicked and loaded, so we do nothing. Otherwise the user has clicked a new link and we need to pull new Ajax results.
The selector for $(“a.sel”) will target any other anchor links on the page with a class of .sel. We want to remove these first so that we aren’t running into problems trying to setup this new link as currently being selected. You’ll also notice I’m adding a small loader gif into the content area before we start the Ajax call. This is a small frontend UI piece to update the user and let them know we are, in fact, loading new results.
The final $.ajax() call is fairly straightforward if you’ve ever seen the syntax before. We’re targeting our ajax.php file and passing in the category ID with the variable name used earlier. If the call is successful we get a whole bunch of HTML data returned, and then display this data into the content container. Super simple and nothing too confusing even for beginners!
Simple Yahoo! Answers API tutorial with PHP
Live DemoDownload Source Code

Final Thoughts

I hope this tutorial has been educational and also a fun learning experience. You can understand a lot of programming concepts by just playing around with online APIs. Tools and resources you would have never thought about become very helpful in managing web applications.
Feel free to download a copy of my source code and implement something similar on your own website. Yahoo! provides very quick response times and their API is one of the best resources online. The online Y! Answers documentation is plenty helpful for getting yourself started on the path of API development.

No comments:

Post a Comment