Customizing an RSS feed using Drupal and Views

Blog | May. 27, 2009

Note: This has only been tested with Drupal 6.x.

For some boneheaded reason, the latest version of Views for Drupal doesn’t let you customize the fields output in an RSS feed. If you create a new feed view, under the Fields block, you’ll get a message saying “The style selected does not utilize fields.” Well la de da. This means you’re stuck displaying the default content, despite which fields CCK says it is displaying or hiding.

Of course. Why would you want to customize your fields, anyway?

So here’s how I was able to customize the RSS fields output by including the entire node in the RSS feed results. If you want a tutorial on how to first setup an RSS feed, there’s a tutorial on creating a custom rss feed in Drupal.

Now that you have your feed setup, you’ll see there’s nothing you can do with it. But there is a Views function you can overwrite in template.php to add more data to the output rows.

/**
 * Default theme function for all RSS rows.
 */
function phptemplate_preprocess_views_view_row_rss(&$vars) {
  $view     = &$vars['view'];
  $options  = &$vars['options'];
  $item     = &$vars['row'];
 
  // Use the [id] of the returned results to determine the nid in [results]
  $result	= &$vars['view']->result;
  $id		= &$vars['id'];
  $node		= node_load( $result[$id-1]->nid );
 
  $vars['title'] = check_plain($item->title);
  $vars['link'] = check_url($item->link);
  $vars['description'] = check_plain($item->description);
  //$vars['description'] = check_plain($node->teaser);
  $vars['node'] = $node;
  $vars['item_elements'] = empty($item->elements) ? '' : format_xml_elements($item->elements);
}

I need to get a real code parser. This is just embarrassing.

What I’ve done above is use the 'result' array and 'id' value returned in the &$vars variable to determine the node ID of the returned results. The ID is just the position the node appears in the list of results (1,2,3,etc.). It’s one higher than the keys to the objects in the ‘results’ array (0,1,2,etc.) so just tell the function to get the nid in the object at position ID minus 1, and now you have the nid of the result. I load the nid into the &$vars array to be sent to the Views template, which I’ll get to now.

Views already has support for templates, but my complaint with its templates — like my complaint with much of Drupal — is that it gives you a half-finished template. It doesn’t give you the perfectly-rendered, nicely polished HTML to want, and it doesn’t give you an array to customize how you see fit: it gives you something in the middle, usually consisting of an array of preformatted elements. So thanks for that. I hope you like all your content wrapped in <p> tags! Well, most of the time, anyway!

Ahem, where was I? Ah, the template. Views recommends using a template called views-view-row-rss.tpl.php (you’ll notice it corresponds to the function name above). This is the most generic RSS template, but you can use a more specific one if you don’t want to use the same formatting on all your RSS feeds. Now that you have the $node variable at your fingertips, you can put any of the node content in the feed. Here’s what I did with it.

< ?php
// $Id: views-view-row-rss.tpl.php 3296 2009-05-27 23:08:21Z timtoon $
/**
 * @file views-view-row-rss.tpl.php
 * Default view template to display a item in an RSS feed.
 *
 * @ingroup views_templates
 */
?>
  <item>
	<title>< ?php print $title; ?></title>
	<link />< ?php print $link; ?>
	<description>![CDATA[< ?php 
		$desc = $node->field_teaser[0]['value'] ? $node->field_teaser[0]['value'] : $node->body;
		print nl2br(check_plain(trim($desc)));
	?>]]</description>
	< ?php print $item_elements; ?>
</item>

Christ how can anyone read that. Fixed! Anyway, nothing too fancy here. I don’t like Drupal’s auto-truncating teaser field, so I’m using my own in a custom field called field_teaser. But if there is no field_teaser value, use the whole node body. I hope this isn’t too many unrelated things to make a clear example.

Now that I have my node’s teaser/body, I trim the content, use Drupal’s check_plain function to do the same thing as PHP’s strip_tags method, and convert the new lines to line breaks using nl2br.

So your RSS reader won’t try to parse those <br /> tags as XML, I enclosed the content in <![CDATA[ ... ]]>, so now you won’t lose any formatting that wasn’t just stripped out by check_plain.

At last, I have a custom-formatted RSS feed showing only the field I want. I can use this to put whatever node content I want into my RSS feed, and if you have been able to follow my rambling example, so can you!

There is another method here: Control Title link and “read more” in RSS Feed of views

Comments

24 Responses to “Customizing an RSS feed using Drupal and Views”

  1. Tim JK says:

    Many thanks – great solution – really helped.

    Your code [formatting?] needs a closing and a closing . Cheers!

  2. Tim JK says:

    Damn! Stripped tags – should have been title and item!

  3. Tim says:

    Good catch, Tim! I’ve updated the post to reflect the missing tags. And sorry about the HTML stripping — WordPress must be paranoid someone is going to fill my comments with <blink> tags.

  4. Ben says:

    This was a great help!! Thanks.

  5. Great solution Tim! I don’t understand why you cannot pick your fields in the RSS display with Views 2 either but your solution should do. SHould have thought about this before. Thanks!!

  6. andrewsuth says:

    Great post Tim, I was scratching my head for hours trying to figure out how to customise my items.

    Now, the next step.. is this also possible for the RSS channel variables too? I tried a few different ways but couldn’t do it.

    Any ideas?

  7. Tine Müller says:

    Hej

    I’m new to Drupal and I’m not sure that I can use your code for what I want?

    This RSS output http://www.tinemuller.dk/drupal/list_copenhagen_feed the text show ABOVE instead of INLINE as it is from the Page that I made the VIEW from as here http://www.tinemuller.dk/drupal/view/list/copenhagen.

    /Tine

  8. Tim says:

    @Tine:

    For some reason it looks like your views-view-row-rss.tpl.php template isn’t being used, or may not exist. If you clear your cache, Drupal should recognize it.

    As for the formatting, ultimately you’ll have to customize the views-view-row-rss.tpl.php template to your own needs, as you would any other template.

  9. Tim says:

    @andrewsuth:

    I believe it’s possible to access the rss channel variables by copying the original $view object into $vars, but I just haven’t tried it (which is why I took months to reply).

  10. This looks like a good solution, but I think it is inefficient.

    Drupal does the initial query of nodes to build the RSS feed. Then your code does a single query to the database for each node in the feed.

  11. Sean says:

    You may also want to have a look at the Views RSS module (http://drupal.org/project/views_rss) – this goes some way to providing the above functionality

  12. Josh Lind says:

    Thanks! I too was struggling through the lack of output with standard Views 2 RSS feeds.

    We should should be able to do this stuff without Views Bonus Pack or Views RSS.

    Now one can, if one feels comfortable with the template.php file.

  13. Kristof says:

    You can also do the following if you want to retrieve the node in the view template.

  14. Dominic says:

    Tim, I just want to thank you for sharing this.
    I was trying out Contemplate and Views RSS templates and none got me where I wanted to go. Your code helped.

  15. ABR says:

    How about if I need to post more then one description ?

    Thanks

  16. klickreflex says:

    Thanks for your solution, it works almost great for me.
    I got on issue: do you have an idea why I can’t seem to output an image inside the description?
    It seems to get stripped out completly when I extend my views-view-row-rss template file like this:
    print $node->field_global_bild1[0][‘view’];

    Should this possibly be inserted into a tag other than ?

    Cheers,
    Daniel

  17. klickreflex says:

    Arrow bracket got stripped out, should read * other than [description]*

  18. Tim says:

    Hi Daniel,

    I haven’t touched this code in awhile, but I would check whether there’s a format filter on the description that strips out HTML, either on the node itself, or happening within Views.

    Or try removing check_plain() from the following line in phptemplate_preprocess_views_view_row_rss():

    $vars[‘description’] = check_plain($item->description);

    Or remove it from within the views-view-row-rss.tpl.php template. Hope that helps!

  19. klickreflex says:

    Hey Tim,

    thanks for your answer.
    It seems the problem was somewhere else:

    The rendered display of my imagefield is not available inside the node object:
    var_dump($node->field_global_bild1[0][‘view’]; returns NULL.

    The image path is available though, so I’m able to build the image link manually using $base_url, $node->field_global_bild1[0][‘filepath’] and imagecache_create_url().

    Much effort just to get a feed formatted the way one wants it to be ^^

  20. Andy says:

    Has anyone tried this with D7? if so how did it work and what did you have to change?

Trackbacks

Check out what others are saying about this post...

  1. […] is a great post over at TIMtheToon that has a great function you can add to your theme to add the full $node data to […]

  2. […] Customizing an RSS feed using Drupal and Views from http://www.timtoon.com […]

  3. […] Views and rss Creating RSS Feeds in Drupal Using Views from www.ostraining.com Using views to publish both full and partial feeds in Drupal from davidherron.com Create Custom RSS Feed With Views Module in Drupal from www.geektips.net Customizing an RSS feed using Drupal and Views from www.timtoon.com […]

  4. […] one of my five friends, or came across this site looking for an (increasingly outdated) way to customize the RSS output of a Drupal feed, then odds are you aren’t even reading […]