Hacking Managing News, part 2: Monitoring topics

Compared to Tattler, one of the weaknesses of Managing News is the lack of topic monitoring - where a user inputs a keyword phrase representing a topic and the system takes care of tracking this topic across pre-selected RSS sources.

Soon after we started using Managing News, this requirement came up. I spent some time understanding BuzzMonitor, the module that implements topic monitoring in Tattler, and then wrote the more boringly-named Feeds Topics to achieve the same thing using Feeds and Managing News.

Here's a recipe of how to integrate Feeds Topics with Managing News. The easiest way is to download the attached MN Topics feature directly! But if you want to know the details, read on.

Installing prerequisites

Configuring the topic infrastructure

  • Create a Topic content type.
  • Create a new importer to turn topics into feeds. Its settings are:
    • Attached to: Topic
    • Import on create: yes
    • Fetcher: Null fetcher
    • Parser: Topic parser
    • Processor: Feed Node Processor with content type = Feed and mapping:
      • title => Title
      • url => URL

Integrating with Managing News

We want to show a new section called "Topics" that displays our topics, the number of mentions found, and an article listing, like so: Topics

  • Create a new view mn_topic_news that is a clone of mn_news. While I won't go into details since the feature is available, I'd like to highlight one major difference: Since we want to display the topic name in the articles list, we need to relate the article to its grand-parent, the topic. This is achieved by adding a relationship between Feed nid (the parent feed) to its owner topic.
  • Create a new view mn_topics that is a clone of mn_feeds. In order to display the mentions, we add a Views Custom Field with the following PHP code:
<?php
$mentions
= db_result(db_query("
SELECT COUNT( * )
FROM {feeds_node_item} source
INNER JOIN {feeds_data_syndication} item ON source.nid = item.feed_nid
WHERE source.feed_nid = %d
"
, $data->nid));
return
$mentions + 0;
?>
  • In order to fix this view's display, we need a little bit of CSS:
/* @file mymodule.css */

div.navbar div#block-views-mn_topics-block_1 div.views-field-title a {
  border-bottom:0;
  padding:5px 5px 0 20px;
}

div.navbar div#block-views-mn_topics-block_1 div.views-field-phpcode span {
  padding:0 5px 4px 20px;
  border-bottom:1px solid #E8E8E8;
  display:block;
}
  • Create new contexts mn-section-topics and mn-section-topics-notrash that are clones of mn-section-news and mn-section-news-notrash, respectively. The main differences involve choosing the views above and setting the menu item to Topics.

Automating feed aggregation on topic creation

Even though we set the topic importer to create its feeds upon creation, the feeds themselves are not aggregated until the next cron run. In order to get the feeds populated upon topic creation, we create a Rule that is fired upon content creation (of type Topic). The action to perform is the following:

<?php
// @file mymodule.module
/**
* Implementation of hook_action_info().
*/
function mymodule_action_info() {
 
$actions['feeds_import_topic_action'] = array(
   
'description' => t('Import a topic'),
   
'type' => 'node',
  );
  return
$actions;
}

/**
* Action function for feeds_import_topic_action.
*/
function feeds_import_topic_action(&$node, $context) {
 
// Import the parent topic by creating the child feeds.
 
if (!$importer_id = feeds_get_importer_id($node->type)) return;
  if (!
$source = feeds_source($importer_id, $node->nid)) return;
 
$source->import();

 
// Import each child feed.
 
$child_feeds = db_query("
    SELECT n.nid, n.type, n.title
    FROM {feeds_node_item} fni LEFT JOIN {node} n ON fni.nid = n.nid
    WHERE fni.feed_nid = %d
  "
, $node->nid);
  while (
$child_feed = db_fetch_object($child_feeds)) {
   
$importer_id = feeds_get_importer_id($child_feed->type);
   
feeds_batch_set(t('Importing !title', array('!title' => $child_feed->title)), 'import', $importer_id, $child_feed->nid);
  }
}
?>

Deleting feeds and articles on topic deletion

When a topic is deleted, we'd like to delete associated feeds and feed items. Here's how to do it:

<?php
// @file mymodule.module

/**
* Implementation of hook_nodeapi().
*/
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if (
$op == 'delete' && ($importer_id = feeds_get_importer_id($node->type))) {
   
// Remove feed from scheduler and delete source.
   
feeds_scheduler()->remove($importer_id, 'import', $node->nid);
   
feeds_source($importer_id, $node->nid)->clear();
   
feeds_source($importer_id, $node->nid)->delete();
  }
}
?>

In order for this to work, we must first modify the FeedsFeedNodeProcessor class by commenting out its method clear:

<?php
// @file profiles/managingnews/modules/contrib/feeds/plugins/FeedsFeedNodeProcessor.inc

class FeedsFeedNodeProcessor extends FeedsNodeProcessor {

 
/**
   * Implementation of FeedsProcessor::clear().
   */
   /*
  public function clear(FeedsBatch $batch, FeedsSource $source) {
    // Do not support deleting imported items as we would have to delete all
    // items of the content type we imported which may contain nodes that a
    // user created by hand.
    throw new Exception(t('This configuration does not support deleting imported items.'));
  }
  */
 
 
...

?>

Feeds Topics is still a work in progress, so your feedback here or in the module's issue queue is appreciated!

AttachmentSize
topics.png91.51 KB
mn_topics-6.x-1.0.tgz16.18 KB

Comments

It Works! ...and its useful.

I've applied the feature successfully at irienews.net and the site really comes alive. To deal with a few glitches I had to manually create the mn_topics view edit the mn-sections-topics context. After that it seem to work, though Im still testing it. I hope this feature can become a part of the Managing News Distro.

Applying this feature

I have a development site that I wish to apply this feature to. I have minimal experience with features and the managingnews profile is an exciting learning experience for me. This is what I have done so far: I downloaded mn_topics-6.x-1.0.tgz, untarred the file, then uploaded the resulting mn_topics folder into profiles -> managingnews -> modules -> features folder. I also downloaded the following modules: Feeds Topics, Rules, Views Custom Field. These modules I placed into profiles -> managingnews -> modules -> contrib. I enabled them through the admin interface. I do not have shell access to this site until Saturday so I am working through gFTP, cpanel, or the admin interface at the site itself to do all of the work. Rest assured on Saturday, drush moves in.

How do I apply this feature?

RE: Applying this feature

I did find this feature to enable in the Features section of Admin (duh) so I enabled it. When I enabled it, did it apply the patch automatically?

You need to apply the patch

You need to apply the patch manually. Since you don't have access to SSH on the host, you need to download the file, patch it locally, then re-upload it.

RE: Applying this feature

Thanks.