hook_node_view

7 node.api.php hook_node_view($node, $view_mode, $langcode)
8 node.api.php hook_node_view(Drupal node Node $node, $view_mode, $langcode)

Act on a node that is being assembled before rendering.

The module may add elements to $node->content prior to rendering. This hook will be called after hook_view(). The structure of $node->content is a renderable array as expected by drupal_render().

When $view_mode is 'rss', modules can also add extra RSS elements and namespaces to $node->rss_elements and $node->rss_namespaces respectively for the RSS item generated for this node. For details on how this is used, see node_feed().

Parameters

$node: The node that is being assembled for rendering.

$view_mode: The $view_mode parameter from node_view().

$langcode: The language code used for rendering.

See also

blog_node_view()

forum_node_view()

comment_node_view()

hook_entity_view()

Related topics

8 functions implement hook_node_view()

1 invocation of hook_node_view()

File

modules/node/node.api.php, line 813
Hooks provided by the Node module.

Code

function hook_node_view($node, $view_mode, $langcode) {
  $node->content['my_additional_field'] = array(
    '#markup' => $additional_field, 
    '#weight' => 10, 
    '#theme' => 'mymodule_my_additional_field',
  );
}

Comments

possible $view_mode contents

possible $view_mode contents include 'full' and 'teaser' amongst others

Has anyone been able to successfully modify a node object?

I note that the node object is not passed as reference and in my own experience with this hook, it's impossible to have changes made to the node (via this call) actually stick. (The title member as an example.)

I know that objects are allegedly passed by reference in PHP but that does not seem to be the case whenever I've attempted to use this function. This page: http://php.net/manual/en/language.oop5.references.php seems to suggest that objects are, in fact, not always passed by reference in PHP.

What am I doing wrong?

(And yes, I know I can use hook_node_alter_view if I really want to change the fields, but it would be so so much nicer if I could just make a call upstream to change what needs changing.)

Thank you.

Perhaps you're looking for

Perhaps you're looking for hook_view which is called before this function and has a return value of the node.

Can't alter that way

Hook_view can only be called by node modules, ones that define the content type via hook_node_info. Maybe you are looking for hook_node_load?

Fishing for hooks

After playing around with this, hook_node_load seems like the simplest way to modify the node object.

However the "proper" way to modify small things seems to be to go down to the field level. But it gets very confusing quickly because there are lots of little hooks (see below) that seem to act on the field & entity level. Furthermore, empty field values don't seem to fire off any of these hooks, i.e. if $node->field_something is null, you can't hook into it.

hook_field_attach_view_alter
hook_field_formatter_view
hook_field_formatter_prepare_view
hook_field_load
hook_field_prepare_view
hook_entity_view_alter
hook_entity_load

It would be helpful to have a visual diagram or flowchart (if it doesn't already exist) showing the sequence of these hooks, and pointing to what part of the data loaded in the hook is actually modifiable. A lot of these little hooks seem to load read-only contextual data (i.e. a node object) or render arrays but for a developer implementing a hook function they want to know how to hook and modify one little part.

Furthermore with so many hooks there are many more places where data is altered, making tracing back changes more difficult than in previous versions of Drupal. Would appreciate any pointers from those in the know.

Return $node

Returning $node in hook_node_view() worked for me.

EDIT: Not returning $node as well is ok. Make sure your PHP version is >=5.2.5

Only $node->content can be altered

Only $node->content can be affected by this hook. Changes to $node->title or other elements are futile.

Don't forget to clear the cache

Don't forget to clear the cache

Watch out for php 5.3 and pass by reference

PHP 5.2.13
Works: function hook_node_view($node, $view_mode)
Works: function hook_node_view(&$node, $view_mode)

PHP 5.3.2
Works: function hook_node_view($node, $view_mode)
Doesn't work: function hook_node_view(&$node, $view_mode)

Here's a discussion on a similar issue with the Webform module:
http://drupal.org/node/765308

Sucessfully managed prepend content to node

I was struggling with this quite a bit, but I have just figured it out. I've posted my code below in case anyone else comes across this problem.

function yourmodule_node_view(&$node, $view_mode, $langcode) {
$strBody = $node->content['body'][0]['#markup'];
$node->content['body'][0]['#markup'] = 'my additional text' . $strBody;
}

Tested on PHP 5.2.10

Kind Regard
Emma

Make sure you use the $view_mode

If you neglect to add a condition to check the view mode then this hook will fire when running cron (not sure why but it does, trust me).

I had a drupal_goto() inside a hook_node_view() which was causing a whole bunch of 'Warning: Cannot modify header information' errors in the logs and cron failed to run because drupal_goto() ends up calling drupal_exit().

So when ever you use this hook always check the view mode like so:

function modulename_node_view($node, $view_mode, $langcode) {
  if ($node->type == 'node-type' && $view_mode == 'full') {
    // Code here.
}

Login or register to post comments