Sorry for what might be NEWB request:

I updated Views yesterday and now it seems the $body variable in my Page > List View template contains EVERYTHING from that node in a string.

Is this the way it is supposed to work? I was hoping to have a variable with just the summary text (the contents of the Body field of my node). Should I be using a different variable altogether? Before I upgraded, $body contained only the text of the body field.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

robknight’s picture

Sort of solved my own issue: I changed "List View" in the View setup to "Teaser" and now $body only contains the body field and my two CCK fields. This makes this a CCK question I guess: How do I control whether those fields show in the $body variable or not?

merlinofchaos’s picture

At this time, the body field displays the constructed body of the node, as through node_view. Drupal's node rendering process is a little opaque, unfortunately. So right now you can't get just the base body field.

robknight’s picture

Sorry: "List View" should read "Full Text" above.

daniel sanchez’s picture

I'm guessing this is the same issue I posted 7/22/2007.
http://drupal.org/node/161284
Because it it an open issue, does it mean that it may be resolved in the future? Or do we need to find a workaround?
Thanks, fellas.

inforeto’s picture

Body is automatically built to include cck fields and other things, rather than use the body field alone.
Use the contemplate.module to be able to modify the output.

Walterh’s picture

I have the same problem. After upgrading the view-module the "body" field got a different definition. First the field "body" only gives the text of the body, but now it gives the complete node as output. This seems as a fundamental change in definitions of this field, and it messes up my site on many places.

I cannot imagine that the "body" field will not be approachable any more in the view model. Is is possible to get this field back?

tom friedhof’s picture

One way that I have overcome this is by intercepting the body handler in views in the template.php file in the function that creates the views list for output. Here is the snippet of code the views theme wizard creates for a list view of your view:

foreach ($nodes as $i => $node) {
    $vars = $base_vars;
    $vars['node'] = $node;
    $vars['count'] = $i;
    $vars['stripe'] = $i % 2 ? 'even' : 'odd';
    foreach ($view->field as $id => $field) {
      // If this is the body field remove the handler
      if ($field['field'] == 'body') {
        $field['handler'] = $views->field[$id]['handler'] = 'just_the_body_field_handler';
      }
      $name = $field_names[$id];
      $vars[$name] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
      if (isset($field['label'])) {
        $vars[$name . '_label'] = $field['label'];
      }
    }
    $items[] = _phptemplate_callback('views-list-location', $vars);
  }

Basically the only thing I changed is I added lines 7-10 in the snippet above. It checks to see if the field being processed is the body field and if it is, it calls another function I defined in the template.php file called just_the_body_field_handler().

That function is just a copy of the views_handler_field_body() function in the views_node.inc file except the the new handler does not call drupal_render, which grabs all the cck fields and puts them into one field, and overwrite the $node->body variable. Here is the new handler that I put in template.php

/*
 * This is an exact copy of views_handler_field_body except that 
 * $node->body is not overwritten.
 */
function just_the_body_field_handler($fieldinfo, $fielddata, $value, $data) {
  $node = node_load($data->nid);

  if ($fielddata['handler'] == 'views_handler_field_body') {
    $teaser = FALSE;
  }
  else {
    $teaser = TRUE;
  }

  $node->body = str_replace('<!--break-->', '', $node->body);

  // The 'view' hook can be implemented to overwrite the default function
  // to display nodes.
  if (node_hook($node, 'view')) {
    node_invoke($node, 'view', $teaser, TRUE);
  }
  else {
    $node = node_prepare($node, $teaser);
  }
  // Allow modules to change $node->body before viewing.
  node_invoke_nodeapi($node, 'view', $teaser, TRUE);
  
  // Allow modules to modify the fully-built node.
  node_invoke_nodeapi($node, 'alter', $teaser, $page);

  return $teaser ? $node->teaser : $node->body;
}

We never get the entire node object in a view, so I've found this being the best way for me.

Although I think if the views_handler_field_body function is being called, it's loading an entire node object already and it should return the entire node object rather than just the return content of the node. Any thoughts?

-Tom Friedhof

guardian’s picture

subscribing

Sutharsan’s picture

Title: $body has everything in Views template » Base body field in View instead of full constructed body
Category: support » feature

I also like CCK to have a way to display the body field only. The current constructed body may remain in CCK as option for compatibility reasons.
In the meantime I will have a try with tomf's method.

Sutharsan’s picture

Category: feature » support

On second thought, there is the alternative to remove the body field (by clearing the body field label text in Home > Administer > Content Management > Content Types > your node type) and replace it with a CCK text field of your choice. I opt for this method and leave the body field behavior in Views as is.

mandclu’s picture

Category: support » feature

I'm forced to use that workaround too, though at this point (with a number of effected nodes already), I need to create the new node field, copy all the content over for each node, and then go back in and delete the standard body field.

It would be helpful if Views offered field options for either the complete, rendered view, or just the content as defined for that field only.

merlinofchaos’s picture

This is the side effect of fixing a bug in the 'body' handling in Views. In order to fix this properly, new code will need to be added to allow you to get just the body field as stored.

The complexity here is in how Drupal completely abuses the 'body' field of the node when generating a node, and at different points it can mean different things. When using CCK, it usually means something much different than when you're not; most of the time, the 'body' means the entire node. But with CCK, people often think of it as just one field.

I'm marking this issue as the bug for tracking these changes for Views 1.7.

BeatnikDude’s picture

me to, tracking

I worked around this by using the contemplate.module and changing my teaser template to:
print $node->content['body']['#value']
And then in the view fields, node body, selected teaser as the handler.

Of course if you are currently using the teasers this is not a good solution.

seanr’s picture

Is no one working on fixing this? This bug makes it very difficult to include the body field as a teaser in a list view. We really need to get this fixed.

seanr’s picture

Category: feature » bug

BTW, this is definitely a bug, not a feature, IMO.

Ryan Palmer’s picture

I'm debating whether this is a views issue or a cck issue.

Assuming it is a views issue, could an option be added to the Node:body field that was something like "Full Text of Body field" instead of just "Full Text" and "Teaser", provided that "Full Text" can potentially include other CCK fields?

caver456’s picture

Grabbing it straight from the database works too. Where you would normally think to do this:
$body=$node->body;
this seems to work instead:

$nid=$node->nid;
$body=db_result(db_query("SELECT body FROM node_revisions WHERE (nid=$nid)"));

but I'm a sql noob, anyone see any gotchas?

doeki’s picture

Agree with seanr, this is a bug:

My block view has Teaser set as handler for the Body field. Still, it shows the whole node.

John Bickar’s picture

Subscribing, although the Contemplate solution worked for my needs.

mariagwyn’s picture

I am having this precise problem in CCK (not using Views for this particular content type) and Contemplate. The $body field dumps everything. #17 above worked for me in my node-jarticle.tpl.php file, though it is not ideal. I will post the question in Contemplate, since contemplate is not giving the option to simply output the body text. Not sure how this helps the VIEWs discussion here, but it is certainly an issue.

Thanks,
Maria

cburschka’s picture

I have the same problem. After some tips, I am going to try and fix this by making my own hook_views implementing module that provides Views with the "node body text" and "node teaser text" fields.

If it works, I will submit a patch against views_node.inc, since that is where Views implements its own hook for the node module.

roald’s picture

Thanks! I'm very interested in the outcome of that work. It would be good to be able to select "node body text" only.

cburschka’s picture

Please note that it'll take me some time to do this. Right now I'm spending pretty much all my Drupal time on getting 6.0 out.

merlinofchaos’s picture

Arancaytar:

Please do submit a patch. This...system existed before CCK was a serious reality, and at that time the idea of body/teaser being truly its own field wasn't really there for me. As time progressed, this part of Views has not caught up with the way things are used.

If you could, simply add additional handler/options to the existing field, perhaps.

cburschka’s picture

Status: Active » Needs review
FileSize
1.64 KB

We probably want to use different function names and different labels than these.

However, the patch works on my site. Using it, I have removed an age-old WTF that required me to hack CCK to display teasers differently, then replace the default node front-page with a view that displayed full nodes, then make a glue module that made said view look like the default. In short, I am very happy with it.

swoodie’s picture

installed the patch. so in the templates, can i simply call print $body now and it should insert only the value of the body field? or do i need to call it differently or do something in the settings? b/c i am still having the same trouble that all custom fields are displaying jumbled below the body text. thanks!

JohnAlbin’s picture

FileSize
2.91 KB

I've been running across this problem all year and I finally wrote my patch this afternoon. And I just found this issue.

@Arancaytar, the code in your views_handler_field_raw_body() is not sufficient to produce a properly prepared body. My patch runs the new handlers through the existing view_handler_field_body() and just skips the nodeapi calls for the new text-only handlers. Also, IMO, the default handler should be the “Full-Page Content”, not “Body Text Only”. That makes it consistent with existing expectations of Views 5.x-1.x users and with the default “full-page” settings in CCK.

@swoodie, after installing the patch, clear the views cache (important!), then edit your view and under the fields next to your Node: body field select one of the new Handlers, “Body Text Only” or “Teaser Text Only.”

(Note that the patch applies cleanly to 5.x-1.x-dev, but not to 5.x-1.6.)

Review, please!

JohnAlbin’s picture

Title: Base body field in View instead of full constructed body » Display "body text only" and "full-page content" handlers for Node: body field
datawench’s picture

i've installed JohnAlbin's patch, and the new options show up in the view edit, but the output is the same.

datawench’s picture

scratch that.
i didn't realize that i needed to switch back to "list view."

so far, this works. thanks :-)

seanr’s picture

Status: Needs review » Reviewed & tested by the community

+1, looks good to me.

seanbfuller’s picture

Status: Reviewed & tested by the community » Needs work

I applied this by hand to a 5.x-1.6 module and I'm seeing a possible issue when a module has a hook_view() function that adds additional elements to the content array on full view of node pages.

I think the issue stems from always passing TRUE in the $page parameter of node_invoke() and node_invoke_nodeapi(). The hook_view() that I am dealing with checks to see if it is a full page view by checking for $page == TRUE. By always sending TRUE as the $page parameter, you always get these additional elements, even when you select "teaser text only"

Maybe setting a $page flag in the function that is set to TRUE and using that flag in the two calls would be the answer. Then you can set $page = FALSE when "teaser text only" is selected. I think that "teaser content" might have the same issue.

To test: Create a module with a hook_view() that adds an element to the content array if $page=TRUE and test each of the conditions.

Setting this to "code needs work" so you can review and see if I'm off my rocker on this one. Feel free to slap me if I'm wrong.

kcplwebteam’s picture

subscribe

pathscollide’s picture

This is a problem for me too. I found this issue after trying to create a table view of G2 Glossary nodes. G2 provides an "Entry expansion (for acronyms) or translation" field, the content of which is saved into the teaser column of the node_revisions table. In Drupal 4.7 I was able to create a nice table view displaying the node title as a link, and the teaser. However, when I try to do this with the current version of views, I get the whole node in the teaser column of my table rather than just the short definition.

sun’s picture

Title: Display "body text only" and "full-page content" handlers for Node: body field » Node: Body outputs entire full node body instead of Body field
Version: 5.x-1.x-dev » 5.x-1.6
Component: Code » node data
Assigned: Unassigned » sun
Status: Needs work » Needs review
FileSize
2.33 KB

#254403: node:body field inserts entire node in view has been marked as duplicate of this issue.

Moving my patch from there over to this issue. I solved this almost identical to John's approach. However, the patches in here are missing the key difference: we want to get $node->content['body'] instead of the whole $node->content in plain output. Also, most modules that alter a node's content act on operation 'view', so this nodeapi operation should be invoked for plain output, too.

Please test.

pastk’s picture

Status: Needs review » Reviewed & tested by the community

It works for me, thanks.
I have replaced my small patch with your's because it is definitely more in-depth.

Summit’s picture

Subscribing..will this be in views 1.7?
Greetings, Martijn

xjm’s picture

Tracking. This has been a major hurdle for me in switching from views 1.5 to views 1.6 (as views 1.5 did not have this behavior). I will test the patch when I get the chance.

Update: Applied the patch, cleared my views cache, modified the affected views--works great. Wish I'd found this patch earlier! Thank you.

joachim’s picture

Patch applied and tested -- works great. Thanks!

+1 for this in a Views 1.x release.

frost’s picture

Patch applied, works perfectky,
another +1 for putting into next Views 1.x release please!

a_c_m’s picture

BRILLIANT !

This is exactly what i needed, applied patch on comment #25 without any problems.... thanks !

Gets my vote to be included in the next release as well!

Robert_SK’s picture

Trying to use contemplate module to customize the page output I came accross the "body problem" discussed here. Studying the body variables provided to me by the contemplate module I found out that the solution was to use $node->content['body']['#value'] as somebody has already mentioned in this thread.

However, I came accross another problem, altough not so serious. I cannot get an access to field labels defined in the CCK module. When I use the contemplate module generate a default custom template for a content type, it just uses <H3> FIELD LABEL </H3>. This is not acceptable, because:

1. The field label is not themed. It should rather look like:
<div> class="field-label">FIELD LABEL</div>
2. The field title cannot be controlled:
a. It cannot be turned off in the "Display fields" section of the CCK module
b. It will still be displayed when the field (in my case an image gallery) is empty

I can "hardwire" the required functionality into the template, but this is not a good solution in the long run. For example, sometime I may want to make the site multilingual. As the field label is not under control of the localizer, I wil run into trouble.

The only occurence of the FIELD LABEL is in: $node->content['field_FIELD NAME']['#value'] inside a long string representing the whole field (in my case an image gallery consisting of an image field with multiple values). I would like a variable like $node->content['field_FIELD NAME']['#label'] to give me the required information.

Renee S’s picture

Is there any way to get a similar patch for 6?

sun’s picture

@z allen: Maybe - after this has been committed to 5.x.

wonder95’s picture

Subscribing

wonder95’s picture

The patch worked perfectly for me.

scip’s picture

Patch worked fine for me

Summit’s picture

Hi, Will this patch go in D5?
Thanks a lot in advance for considering.
Greetings,
Martijn
www.vindtocht.nl

wonder95’s picture

Probably not, since all development is going into D7 now.

sun’s picture

Please don't spread FUD. Patch in #35 will most likely be included in 1.7.

wonder95’s picture

Oops, sorry. My bad.

emdalton’s picture

Does this behavior occur in Views 2 in D6, and if so, can this patch be adapted to fix that? I use the Contemplate workaround, but it's a nuisance, and if anyone ever takes over maintaining this site after me, they'll have a very difficult time understanding what I did and why.

Mike Kennedy’s picture

Version: 5.x-1.6 » 6.x-2.3

I am having the same problem with Drupal 6 views 2. Is there anyway to set the Field Node Body to show the text only?

Currently the Field Node Body shows images as well. Is there a solution to prevent images from showing?

Thank you in advance?

xjm’s picture

Version: 6.x-2.3 » 5.x-1.6

Probably want to keep this issue for the 5.x version, since there exist people who are still using it, and create a new issue for 6.x. (And Views 1.7 does not exist, contrary to the above.) The patch can probably be ported, but create a new issue. You can always link this issue and its patch.

The question about images depends--are the images in separate fields, or in the main body field? Also should have its own issue, but you could resort to .your-views-class-here img { display: none; } if you simply want to make existing body images not appear in your view.

samdds’s picture

Hello, I'm having the same problem with D6, is there a patch for this?

dawehner’s picture

Please open a new issue for drupal6.

samdds’s picture

No need to, solved it:

<?php print $node->content['body']['#value']; ?>
esmerel’s picture

Status: Reviewed & tested by the community » Closed (won't fix)

At this time, only security fixes will be made to the 5.x version of Views.