Profile picture for user admin
Daniel Sipos
13 Mar 2013

This week’s post will look at how to use hook_node_view() to add or change node content before being rendered on the page. This is a powerful API tool used by many contrib modules to intervene at this final stage when the renderable array is already created.

To illustrate the power of this hook, I will first show you how to add new content to the node being displayed on the page. Additionally, I will show you how to programatically change the display style of an image field using this hook.

Like I said, hook_node_view() gets called in the final stage of content delivery, after it is assembled and before is being rendered onto page. Moreover, it takes three parameters: $node (the node being assembled), $view_mode (the view mode it is currently on), and $langcode (the language code).

Adding or modifying node content

In the first example, let’s say we have Article nodes which have a body and an image field. Below these fields, we want to add a list of items that our module generates dynamically depending on the node being loaded. In this example, I’m going to hardcode this list because it is not the focus of the article, but you’ll get the point.

A simple function to return an array that will constitute the list items:

function demo_get_list_items() {
  $array = array("car", "cat", "dog");
  return $array;
}

Now we can look at the hook. I will write the code and then explain:

function demo_node_view($node, $view_mode, $langcode) {  
  $array = demo_get_list_items();
  $list_vars = array(
    'items' => $array,
    'type' => 'ul',
  );
  if($view_mode == 'full') {
    $node->content['list'] = array (
      '#markup' => theme('item_list', $list_vars),
      '#weight' => 3,
    );
  }
}

First of all, I advise you to use the Devel module to look inside the $node object for orientation. The $node->content array is what in Drupal talk you call a renderable array, ready to be displayed on the page. This is where we include our list, right below the body field.

So the function above does the following. First, it retrieves the list items and prepares another array to be passed to the theme() function later on. Then, it checks to see that the view mode of the node is 'full' (to avoid this injection to be done in teasers or other view modes).

Inside this conditional, a new array is set within the $node->content array, with the key list. We pass the markup to be used for our list and the weight (in this example 3 is fine since we want it to come at the end of the Article node fields).

The theme() function will use the Drupal item_list theme to render our array into an unordered html list. We pass it also the array of parameters we declared a bit earlier.

And this is pretty much it. If you clear the cache and go see any node, you’ll see your list appear below the body field. But I’ll let you go ahead and figure out how you can limit the list to appear only on Article nodes. Hint: krumo the $node object and use what is in there in the php if conditional.

Note: Using this hook does not add any new information to the database nor it creates new fields attached to the node. If the module gets disabled, the content you add using this hook will no longer appear. Additionally, if you use something like the Display Suite module to create custom layouts for your nodes, content you add outside of already existing fields will not show.

Changing the image style

This second example comes from what I promised you last week and is quite simple in fact. All you need to do is replace the image style used for rendering the image in the node. This is the code:

function demo_node_view($node, $view_mode, $langcode) {  
  if($view_mode == 'teaser') {
    $node->content['field_image'][0]['#image_style'] = 'demo_image';
  }
}

Here, we make sure that our demo_image image style gets applied only to nodes being viewed in teaser mode. Within the php conditional, we simply replace the #image_style property of the image field. And that’s it. Clear the cache and you’ll see the changes.

So these are very simple ways you can use hook_node_view(). If you look what the $node object gives you to work with, I'm sure you can find many uses for this hook. Incidentally I used it in my contrib module Block Inject to make changes to the body field. Check it out if you want to see how I used it there.

Hope this helps. Any trouble, drop a comment.

Profile picture for user admin

Daniel Sipos

CEO @ Web Omelette

Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.

Contact us

Comments

Sampo Turve 14 Mar 2013 08:00

Note that you can also use

Note that you can also use #theme (+ the theme function parameters) without need to call the function yourself. Like this:


function demo_site_node_view($node, $view_mode, $langcode) {
if ($view_mode == 'full') {
$node->content['list2'] = array (
'#theme' => 'item_list',
'#items' => demo_get_list_items(),
'#type' => 'ol',
'#weight' => 0,
);
}
}

Daniel Sipos 14 Mar 2013 10:26

In reply to by Sampo Turve (not verified)

Hey there, thanks for your

Hey there, thanks for your comment.
Indeed you are right, but I wanted with this occasion to also show the use of the theme function -> if you can squeeze more API tools in there, why not? :)

Cheers!

Raheel 05 Oct 2014 00:22

Trying to edit the title for node but no result

Hi,
Thanks for the information. I am by following your tutorial i used devel module and there i find $node->title which is the title of the node currently being viewed. How ever in the mentioned hook i tried to overwrite the title but nothing is changed.

Can you please clear this confusion.

Thanks

DS 16 Oct 2014 19:50

setting the title

You may be looking for drupal_set_title();

http://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drupal_set_title/7

vulfox 23 Mar 2015 20:44

node_view_alter ?

Hello!

I have been banging my head with Drupal theming all evening now and wondering why you use hook_node_view
and not hook_node_view_alter
or hook_entity_view_alter?

Lost101 12 May 2015 16:45

A little help please!!

Hi there,
A lot more to grasp from your content but a little help will be appreciated,
what if:
I create a blog listing view in which it show several blogs in teasers form which displays(presently) blog title, blog content, than its image but i want to display blog image, title than blog teaser can i achieve that in Views thanks in advance

Oleg 05 Nov 2015 23:45

Mistake ?

Hello!

Probably you have to write on second line
$array = demo_get_list_items();
instead of
$array = get_list_items();

Daniel Sipos 07 Nov 2015 15:29

In reply to by Oleg (not verified)

Hey there, Thanks! Corrected.

Hey there,

Thanks! Corrected.

W.M. 21 Mar 2016 20:37

How to add CSS class to the

How to add CSS class to the inserted field or HTML markup? Thanks.

chetan 24 Sep 2016 10:25

add custom div before the node title

I am trying to add custom div before the node title please guide me.

yinon 18 Nov 2020 11:23

tahnks

Explanations and examples are really good
Very helpful article
Thank you

Add new comment