6

I load an Article node with node_load() and I'd like to get the summary for the Body field. I know that I can access it with $node->body[$node->language][0]['summary'] but unless the user explicitly adds a Summary Body, then this field is empty.

I know that drupal will automatically generate a "trimmed body" if they don't add a Summary Body. How can I access that trimmed body?

EDIT:

I'm not interesting in render()ing the content, I just want the text. My module is generating a json feed for an external source.

4 Answers 4

11

node_view() is appropriate when you need to render whole node or many of it's fields.
But sometimes you have to render the only field you need. It can be done with field_view_field() or field_view_value():

$node = node_load($nid);
// Render array of body field.
$build_body = field_view_field('node', $node, 'body', 'teaser');
// Render it in common way.
echo render($build_body);

The interesting thing is that you can pass your own field formatter settings instead of view mode with the fourth parameter. Please, read API docs for more info.

1
  • Thanks, I'll check these out! You may have answered another question I had as well. Commented Jul 5, 2012 at 16:50
5

A fairly detailed discussion on this topic is on Drupal 7 How to load a teaser programatically.

$teaser = render(node_view(node_load($nid), 'teaser'));
print $teaser['body'][0]['#markup'];
2

I wan't summary field always filled then I use something like this function (in custom module):

/**
 * Implements of hook_node_presave().
 */
function mymodule_node_presave($node) {
  // if is summary not empty we can continue
  if (isset($node->body[LANGUAGE_NONE][0]['summary']) && !empty($node->body[LANGUAGE_NONE][0]['summary'])) return;

  // we use module smart_trim to create smart trimmed variant of summary
  $build_body = field_view_field('node', $node, 'body', array(
    'type' => 'smart_trim_format',
    'settings' => array(
      'trim_length' => 8,
      'trim_type' => 'words',
      'trim_suffix' => '...',
      'more_link' => FALSE,
      'more_text' => 'Read more',
      'summary_handler' => 'full',
      'trim_options' => array(
        'text' => TRUE,
      ),
    ),
  ));

  // store created summary
  $node->body[LANGUAGE_NONE][0]['summary'] = $build_body[0]['#markup'];
}

Module smart_trim is used as renderer for summary.

2

For anyone interested, here is the most minimal solution. I will use db_select to execute the query rather than node_load.

//first build the query
$query = db_select('node', 'n');
$query->fields('n', array('nid', 'title', 'language'));
$query->join('field_data_body', 'body', 'body.entity_type=\'node\' && body.deleted=0 && body.entity_id=n.nid');
$query->addField('body', 'body_value', 'body_value');
$query->addField('body', 'body_summary', 'body_summary');
$query->addField('body', 'body_format', 'body_format');

//fetch a single item as an associative array
$item = $query->execute()->fetchAssoc();

//If an explicit summary has not been provided, we generate it here
if (empty($item['body_summary'])) {
    $summary = check_markup($item['body_value'], $item['body_format'], $item['language']);
    $item['body_summary'] = text_summary($summary, $item['body_format']);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.