I've searched this forum for months and not found anything. Here is the situation...

We have a website with 25,000 articles and 240 categories (http://www.sportbusiness.com/). Each news item is a CCK (written by JonBob) type. I developed a custom module to generate the menu on the left which uses the top terms of the vocabulary by nodes-per-term. When you select a term, it takes you to the taxonomy/term/[tid] page which is provided by the wonderfull Views Module (written by MerlinOfChaos). All this worked perfectly. Whenever a news items gets added (5 or 6 a day) it automatically appears in the correct pages. Fantastic... But life isn't that easy. The RSS feeds would not work correctly with the CCK nodetype. The views_rss.module didn't know what the teaser was - afterall, CCK does not have teasers. Instead, it was taking the HTML of the body and our description field ended up looking like a HTML Entity encoded version of the body! Not ideal...

After talking with robertDouglass, reading through a number of posts including the views documentation and finally looking at the views_rss.module, I realised that the $node->teaser needed setting before the XML was output. In the views_rss.module there was a pair of lines (currently 131-132 at time of writing - version 1.7) which read...

      // Allow modules to change $node->teaser before viewing.
      node_invoke_nodeapi($item, 'view', $teaser, FALSE);

... and I recalled Rob mentioning the nodeapi. A quick peek at the documentation, a few print_r debug statements later and I ended up with this code...

function newsitem_nodeapi(&$node, $op, $teaser = FALSE, $page = FALSE) {
  if($node->type =='content_newsitem' && $op == 'view' && $teaser) {
    $node->teaser = $node->field_story_stand_first[0]['value'];
  }
}

... which basically checks the content type, the operation (only interesting in viewing) and if the teaser is set. Techinically - according to the docs, $teaser and $page should be $a3 and $a4 - however for readability and my own sanity I used $teaser and $page. Once we know we have the correct situation, I set the teaser to the "story stand first" field which, on our news stories, is the bold first paragraph.

I hope people find this usefull - I spent ages looking for a definative sollution and couldn't find one. For an example of the feed produced, try our American Football newsfeed

Comments

fangius’s picture

After a thorough search of the forums I posted questions concerning just this only minutes ago!
I was just reading the docs about node_feed in api and was thinking of having a go the way you suggested when I spotted your poroposal. Can't wait to try your code. Looks promising! Thanks for the info.
Probably the solution for these guys as well: http://drupal.org/node/83933, http://drupal.org/node/63883 and maybe the issue by kiteatlas at http://drupal.org/node/87027.

soundstripe’s picture

Can you please tell me what file you placed your custom nodeapi hook function in? It appears that it is the sort of thing that would go in a .module file, but it sounds like you were placing it in your template.php? I need to do the exact same thing for some CCK node types that I've created.

Thanks,
SJ

nicholasthompson’s picture

I put it in newsitem.module

coupet’s picture

Excellent tips!

----
Darly

ThePants’s picture

This is not working for me.

I created a file called views_rss_custom.module in my site's module directory with these contents:


function views_rss_custom_nodeapi(&$node, $op, $teaser = FALSE, $page = FALSE) {
  if(($node->type =='content_blog_entry' || $node->type =='content_blog_entry___links' ) &&
       $op == 'view' && $teaser) {
    $node->teaser = $node->field_teaser[0]['value'];
    // print $node->teaser; 
  }
}

When I uncomment that print line it prints the correct teaser, however the rss feed still prints out the ugly auto-generated content.

Looking in view_rss.module on line 139-141, if I add a line to print $item->teaser it also prints the ugly auto-generated content.

      // Allow modules to change $node->teaser before viewing.
      node_invoke_nodeapi($item, 'view', $teaser, FALSE);
      print $item->teaser;

It's almost like the pass-by-reference to my nodeapi hook function isn't "sticking". Are there any other modules' hook functions that would run after mine to undo all my work or something?

ThePants’s picture

I changed my module's weight to 9999 using the sample SQL here: http://drupal.org/node/110238
and the teasers are now working in rss as advertised.

heine’s picture

Better not use the value field as it has not been transformed into a useable 'view' of the data. That means for example, that filters from the input format have not been applied. Apart from minor inconveniences such as no URL autolinking, it opens an avenue for cross site scripting when users are able to submit this content type. A well executed cross site scripting attack may lead to users obtaining administrator privileges on your site.

Use the formatted, view field ($node->field_teaser[0]['view']) instead.

--
The Manual | Troubleshooting FAQ | Tips for posting | How to report a security issue.

bsuttis’s picture

Code above works great, but I'm finding that while CCK text and image fields will output, I can't get a CCK URL or email field from the same URL to output in my RSS feed.

Is this something to do with the design of Email/URL CCK field modules?

edzhus’s picture

I created new module called views_rss_cck with code:

function views_rss_cck_nodeapi(&$node, $op, $teaser = FALSE, $page = FALSE) {
  if($node->type =='raksts' && $op == 'view' && $teaser) {  
    $node->teaser = theme('imagecache', 'galvena_garena', $node->field_raksta_attels[0]['filepath']) ."<br/>". $node->teaser;  }
}

It will display image in field "field_raksta_attels" and then after line break nodes teaser. "galvena_garena" is for imagecaches preset.
Hope this will help you!

ar-jan’s picture

I am trying to use the code examples given here to customize the Views RSS output, but I don't know how exactly to do this. I tried making a custom module based on above example, without luck.
The output of an RSS item in the Views preview for my content type contains the following items:

<item>
 <title>
 <link>
 <description>
 <comments>
 <category>
 <pubDate>
 <dc:creator>
 <guid>
</item>

I want the feed to contain only title, pubDate and description (= teaser content). Anybody know what the code should look like? (D6.4, Views2).

johngrinde’s picture

First thing to get out of the way: I'm using Views theming by copying files into my theme directory; I'm not using Contemplate.

After playing around a bit, I've discovered that if I enclose some standard HTML within an if $node statement, it does not return any output, while it functions perfectly without the if statement.

Edit: I'm on Drupal 6, by the way.

Example

<?php if ($node): ?><p>Testing 1-2-3</p><?php endif; ?>

So as far as I can tell, the RSS templates do not appear to load $node, which seems to be why we can't get custom fields inserted. I'm a beginner to PHP, and not currently using Drupal on a production site, and this is one thing that may hinder me from moving to Drupal.

Anyway, thanks for the help!
-John Grinde

ar-jan’s picture

I haven't tried it but maybe this can help: http://drupal.org/project/extra_RSS_fields

Lams’s picture

You may have to use the DEFAULT RSS SETTINGS in the view.

In the feed tab, click on row style> node. In the resulting div, click on settings and select 'default rss settings'

I have a custom type with a views RSS in drupal 6. I was able to get control of the RSS in a custom module with a hook_node_api implementation. switching on the $op as below. In the node available to my RSS feed (using print_r), I was finding it impossible to find my CCK field that i needed to output (line 2). It just wasn't there. Even though I was using a setting of 'full text'. Changing this to 'default rss settings' made it available.

case 'rss item':
$node->teaser = $node->field_articles_teaser[0][view];
break;