Practical Drupal Development #4 - How to put the image field above the node title

Drupal

This is the episode number 4 of Practical Drupal Development. This time I'm going to show you how to put the image field above the node title. As always, I'm going to pose a practical issue in order to help you understand how it's made.

Issue to be solved

As you can see in many premium themes for Drupal, there is a growing trend towards putting the image field above the node title. Imagine that you are told by a client, who likes to be up with the latest trends, to make his blog entries look like those that set a trend.

Node of type Blog with the image field below the title

Theme hook suggestions of templates files

In order to format blog entries only, you need a way of telling Drupal that you do want to put the image field above the node title just for nodes of type Blog. In Drupal parlance that way is called theme hook suggestions, that is, you can provide context to the theme system by using a theme hook pattern. This is how it works:

[base hook]__[context]__[more context]
[node]__blog__1
node--blog--1.tpl.php

The parts of the pattern are separated by using a double underscore. In this example you are going to use a double hyphen since you'll be using templates files. If you used theme(), then you'd have to provide a theme hook pattern as its first parameter with the double underscore for separating the different suggestions/contexts.

As you want to format nodes of type Blog only, you'll use the next theme hook pattern:

[base hook]__[context]
[node]__blog
node--blog.tpl.php

which means that you have to create a new file to be named node--blog.tpl.php inside the templates folder and paste the content from node.tpl.php into it. If you wanted to put the image field above the title of each node (regardless of the type), then you'd have to edit node.tpl.php.

OK, it's time to edit node--blog.tpl.php, so open it with your favourite text editor or IDE.

As you can see in the following image, I'm using the Bartik's theme implementation to display a node; that is, I'm using the node.tpl.php that falls under themes/bartik/templates. As you can guess, there may be some or a lot of differences with the markup between this template and the one you use.

Bartik's theme implementation to display a node

Here's a rough outline of what you'll do in order to alter the markup of node--blog.tpl.php properly:

  • Where is stored the image that is used by each blog entry?
  • Where in the markup do you have to write the piece of code to put the image above the node title?
  • How can you print just an item that is included in a set of node items?
  • How can you hide an item that is included in a set of node items?

As you can read in the previous image, the variable $content is an array of node items. In order to print just one of those items, you have to use a function called render(). In addition, you must provide as its single parameter the place where the image is stored in the array. In this case the function would look like as follows:

render($content['field_image'])

Hey! How can I know the right key to be written between those square brackets? The key to be written between the square brackets matches the field's machine name. You can search for its name on the page to manage blog entry fields:

Page to manage the fields for the blog entries

Now you have to write the previous piece of code (along with the reserved word print, of course) somewhere in node--blog.tpl.php. The right place is at line number 82. You can see it in the following image:

Bartik's theme implementation to display a node with the new pieces of code.

There is one more step to be done. As said above, you must hide the image field to not be included twice in each node. How can you do that? Please have a look at line 104 in the previous image.

Since you have already put the image above the node title, you must prevent the theme system from rendering it twice. You can do that by using the function hide(), which would look like as follows:

hide($content['field_image'])

As with the render() function, you must provide as its single parameter the place where the image is stored in the array. Remember, field_image is the field's machine name that you want to hide. And... Voilà!

Node of type Blog with the image field above the title