Mapping additional fields (ex.g. feed original source) with Feeds

The relatively new "Feeds" module, successor to Feed API and others, is unquestionably a move in the right direction. But sometimes, the documentation and examples aren't quite there yet. I had been trying to figure out how to map an additional "source" node in an Atom feed to a CCK field. There's a lot of terminology involved with feeds, and I will assume you know what that is (if not, brush up on the Feeds Glossary).

Here's my use case. I wanted to allow a person to monitor multiple sources without having to import every item from every RSS feed being watched... so first I wanted to run it through an external filter... enter Google Reader. Using Google Reader, you can use Google Reader's "Shared" or "Starred Items," each of which will generate an Atom feed. You can then import that Atom feed into your Drupal site. Then, each node that is created at the target is one that you already for-sure want on your site.

The only problem with this approach is that getting the original source of your feed means an extra step (because the immediate source is actually "Items Shared from Google Reader"). However, the original source is inside the "entry" node of the Atom feed (under the "source" node, then the "title" node).

To get this, we can extend the SimplePieParser (which first must be properly installed; see the README for Feeds... essentially you need to download the SimplePie library before that Parser will become available to you).

Using the example at The developer's guide to Feeds, we see that we must do three things:

  1. Implement hook_feeds_plugins
  2. Create an inc file to extend the SimplePie parser
  3. Configure our feed to use our parser instead of SimplePie

Step 1 - Implement the hook to tell feeds about your parser. You will need to create your own custom module.

<?php
function MYCUSTOM_feeds_plugins() {
 
$info = array();

  if (

feeds_library_exists('simplepie.inc', 'simplepie')) {
   
$info['MYCUSTOMParser'] = array(
     
'name' => 'My custom parser',
     
'description' => 'Inherits the SimplePie parser and then extends it for custom  fields.',
     
'handler' => array(
       
'parent' => 'FeedsSimplePieParser',
       
'class' => 'MYCUSTOMParser',
       
'file' => 'MYCUSTOMParser.inc',
       
'path' => drupal_get_path('module', 'MYCUSTOM'),
      ),
    );
  }

  return

$info;
}

function

MYCUSTOM_enable() {
 
//clear the cache to display in Feeds as available plugin.
 
cache_clear_all('plugins:feeds:plugins', 'cache');
}
?>

...take particular note of the "parent" sub-key, that needs to be FeedsSimplePieParser, or you'll get a "class not found" type of error.

Then, you need to actually make "MYCUSTOMParser.inc" - this is a CTools-style plugin file. It goes in your module folder (as specified by the "path" sub-key above).

<?php
/**
* A simple parser that extends FeedsSimplePieParser by adding support for a
* couple of other tags.
*/
class MYCUSTOMParser extends FeedsSimplePieParser {
 
/**
   * Add the extra mapping sources provided by this parser.
   */
 
public function getMappingSources() {
   
$sources = array(
     
'source_title' => array(
       
'name' => t('Source Title'),
       
'description' => t('Source Title of the Feed Item.'),
      ),
    );
   
    return
parent::getMappingSources() + $sources;
  }

 

/**
   * Parse the extra mapping sources provided by this parser.
   */
 
protected function parseExtensions(&$item, $simplepie_item) {
    if (
$value = $simplepie_item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source')) {
     
$item['source_title'] = $value[0]['child']['http://www.w3.org/2005/Atom']['title'][0]['data'];
    }
  }

}

?>

...you'll not that my $item['source_title'] is being assigned something from the original SimplePie parsed object. It's quite a ways to traverse down, but it works.

Lastly, you need to go to your "Feed" feed importer (at admin/build/feeds/list) and edit it (this will override the defaults). Change the Parser to be your custom parser, and not the "Common Syndication" or "SimplePie Parser" you had before. Remember, since this is inheriting everything from the SimplePie Parser anyway, you are getting the SimplePie parser, PLUS your new stuff. That's the beauty of object-orientation and CTools plugins!

I hope this helps someone else with a similar use-case.

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <h1> <h2> <h3> <h4> <h5> <h6> <img>
  • You may post code using <code>...</code> (generic) or <?php ... ?> (highlighted PHP) tags.
  • Lines and paragraphs break automatically.

More information about formatting options