jQuery: RSS reader

Fetching a remote RSS feed with jQuery is one of the most frequently asked questions in a million. jQuery can't handle a remote feed by itself due to the same-domain policies of the AJAX standard. For that reason, we need a server-side script which accepts two parameters, namely the absolute URL of the feed and the number of items you want to display. In our example we'll use PHP, obviously after making sure that the passed URL is a valid URL and that we're actually dealing with an RSS feed. Here's the script:

header('Content-Type: text/html; charset=UTF-8');

$feedURL = $_GET['u'];
$limit = $_GET['items'];
$html = '';
$cnt = '';

if(filter_var($feedURL, FILTER_VALIDATE_URL)) {

   if(file_get_contents($feedURL)) {
   
     $ch = curl_init($feedURL);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ch, CURLOPT_HEADER, 0);
     $data = curl_exec($ch);
     curl_close($ch);
     
     try {
     
        $doc = new SimpleXmlElement($data, LIBXML_NOCDATA);
        
     } catch(Exception $e) {
     
       $html = '<p>Error: Invalid XML.</p>' . "\n";
       echo $html;
       
       exit();
     
     
     }
     
     if(isset($doc->channel)) {
     
       $html = '<div class="feed">' . "\n";
       $html .= '<h2>' . $doc->channel->title . '</h2>' . "\n";
       $items = count($doc->channel->item);
       
       if(isset($limit)) {
       
          if(is_numeric($limit)) {
          
            if($limit < $items) {
            
                $cnt = $limit;
            
            
            } else {
            
              $html = '<p>Error: too many items requested.</p>' . "\n";
              
              echo $html;
              
              exit();
            
            }
          
          
          } else {
          
            $html = '<p>Error: items must be a number.</p>' . "\n";
            
            echo $html;
            
            exit();
          
          }
       
       
       } else {
       
       
         $cnt = $items;
       
       }
       
      
       
       for($i=0; $i<$cnt; $i++) {
       
         $url= $doc->channel->item[$i]->link;
      $title= $doc->channel->item[$i]->title;
      $desc = $doc->channel->item[$i]->description;
      $date = $doc->channel->item[$i]->pubDate;
      
      
      $html .= '<div class="entry">' . "\n";
      $html .= '<h3><a href="' . $url . '">' . $title . '</a></h3>' . "\n";
      $html .= '<div class="date">' . $date . '</div>' . "\n";
      $html .= '<p>' . $desc . '</p>' . "\n";
      $html .= '</div>' . "\n";
 
       
       
       }
       
       $html .= '</div>' . "\n";
     
     
     
     } else {
     
       $html = '<p>Error: This is not an RSS feed.</p>' . "\n";
     
     }

   
   
   } else {
   
     $html = '<p>Error: File Not Found.</p>' . "\n";
   
   }


} else {


   $html = '<p>Error: Invalid URL.</p>' . "\n"; 

}

echo $html;

This script returns an HTML structure containing the feed data (or an error if something goes wrong). The structure is as follows:

<div class="feed">
 <h2><!--feed title--></h2>
 <div class="entry">
   <h3><a><!--entry title and link--></a></h3>
   <div class="date"><!--RSS date--></div>
   <p><!--entry description--></p>
 </div>
 <!--more entries-->
</div>

The script accepts two GET parameters:

  1. u: A full, valid URL.
  2. items: The number of items you want to display (optional). If omitted, all the RSS feed content will be returned.

Now we have to create our jQuery code. For this example, I decided to create a small plugin that inject the feed data in the HTML element is attached to:

/** jQuery RSS Reader
    @version 1.0
    @author Gabriele Romanato <http://onwebdev.blogspot.com>
    @description Retrieves a remote or local RSS feed.
    
    Usage: $(element).rssReader(options) */
    
(function($) {

  $.fn.rssReader = function(options) {
  
    var defaults = {
      url: 'rss-fetch.php',
      feedURL: false,
      items: false
    };
    
    var that = this;
    
    options = $.extend(defaults, options);
    
    return that.each(function() {
    
    
        if(!options.feedURL) {
        
          throw new Error('You must specify a feed URL.');
          return;
        
        
        }
        
        if(options.items) {
    
      
        $.ajax({
          url: options.url,
          data: 'u=' + options.feedURL + '&items=' + options.items,
          type: 'GET',
          success: function(html) {
          
            that.html(html);
          
          
          }
       });
       
       } else {
       
         $.ajax({
          url: options.url,
          data: 'u=' + options.feedURL,
          type: 'GET',
          success: function(html) {
          
            that.html(html);
          
          
          }
       });

       
       
       }
    
    
    });
  
  
  
  };



})(jQuery);

This plugin accepts three options:

  1. url: The exact location of the PHP script.
  2. feedURL: The remote feed URL. It cannot be empty.
  3. items: The numbers of items you want to display (optional). If omitted, the entire feed will be returned.

As you can see, our plugin simply assembly the GET parameters using the $.ajax() wrapper with data and fills an element with the returned HTML contents. An example:

$(function() {

  $('body').rssReader({
    feedURL: 'http://feeds.bbci.co.uk/news/technology/rss.xml',
    items: 6
  });

});

You can see the demo below.

Demo

Live demo

Leave a Reply

Note: Only a member of this blog may post a comment.