paul bennett

Drupal: Creating custom node templates

Posted on: May 28, 2009

It has somewhat of a steep learning curve, but Drupal is amazing for allowing you to build flexible, complex websites with lots of functionality in very little time.

For a site I’m working on, we had several custom content types coming through the default node template (node.tpl.php) in our customised theme.

This was fine and dandy for quick development, but then the time came to customise the node page for each content type.

First things first, you need a custom node template. Save the node.tpl.php file as node-[your node name].tpl.php and you’ve created a custom node template. (This means if your node type is ‘audio’, you’d save the file as node-audio.tpl.php)

Now we need to customise the template to suit our needs.

If you dive into a standard node template you’ll see something (unhelpful) like this where the content goes:

<div class=”content”>
print($content)
</div>

Um, OK. So how do you get at the functions which compile the content before it gets to this stage? Well, you probably can, but the easier way is to avoid this step and just access the default $node object which drupal gives you access to with each ‘page’.

To find out what’s hiding inside the $node object, simply do something like this:

print_r($node);

(Yes, I like print_r())

The resulting cacophony in your page source will show you all the node attributes and properties you have access to. Chances are you’ll be able to access these directly to create the customised node template you need.

22 Responses to "Drupal: Creating custom node templates"

Thank you so much for this post…this was exactly what I needed to create custom templates. I appreciate your effort!

@Benjamin,

Thanks – it took me a while to figure this out and it didn’t seem to be that well documented, so I thought I’d throw it out there.

🙂
Paul

There seems to be an awful lot of duplication in CCK arrays that are produced from the print_r statment, how do you know which one to use.

[#item] => Array
(
[value] => Keppoch Street
[safe] => Keppoch Street
[#delta] => 0
)

bit further down it says
[#children] => Keppoch Street

and again

[#children] => Keppoch Street

under a different part of the array.

Why is it repeated so many times?

Hi Bobby,

I’m no expert (by any means), but I think Drupal stores the CCK fields as children of the default node.

In your case it looks as though the street is a CCK field, which will be included in the outputted $node->content, but Drupal also shows the field relationship as a child of the main $node (hence I guess CCK fields are all classed as ‘children’ of the default raw $node).

As for what to use, I usually use the $node->content[‘field_name’][‘#value’] field.

I usually use the $node->content[‘field_name’][‘#value’] field.

Hi Benji,

Yep, I probably should have been a bit more specific in my post, but I was trying to be applicable to any content type.

Luckily viewing the output of print_r($node); shows you pretty quickly what the best output field is to use for any given situation.

Paul

just wanted to second (third) the thanks, this is what I needed to move on from my stuck-ness.

Sorry but I am pretty new to Drupal still and I only followed the first half of your post.

Where do you put the “print_r($node);” to show the node object?

I have a custom event content-type that I want to filter for a calendar.

@Wayne,

In the custom node template you’ve created, replace:

print($content);

with this:

print_r($node);

when you view the page source, you’ll be able to see the full structure of the node object and can then pick and choose which fields you have in your template and how you show them.

🙂
Paul

Sometime you’ll need to replace $node->content[‘field_name’][‘value’] , with $node->content[‘field_name’][‘view’] . That will keep any formatting (such as line breaks) intact. Took me a while to figure that one out… hope it helps.

Thanks Daniel,

Yep, you’re right – the exact part of the $node object best to use depends upon the need – especially when CCK is in the mix

🙂
Paul

This is a great post. I’m new to Drupal and have used this method to customize the output of one of my custom content types. Combined with CCK this is very helpful.

However, I’ve been wondering, is this the “correct” way to achieve this. Once I do this, I am tied to the theme I modified, correct? If I change themes, I need to copy my node-custom.tpl.php file to the new theme.

It seems like there should be a way to tie a node template to a specific content type, rather than a specific content type in a specific template. Any thoughts?

Hi Brandon,

There probably is but I haven’t found it (yet).
If / when I do I’ll be sure to post.

Paul

In order to make your custom node template independent of the current theme you are using you need to create a subtheme containing your node-custom.tpl.php file.

Instructions for creating subthemes can be found at:
http://www.advantagelabs.com/how-create-subtheme-drupal-6
http://drupal.org/node/441088

Basically, you need to
1. create a folder for your subtheme
/sites/all/themes/
2. create a .info file for your subtheme
3. Put your node-custom.tpl.php in your new subtheme folder

I’ve tried looking through the entire $node->content object to try and reference a field using

$node->content[‘field_regeventday’][‘#value’]

$node->content[‘field_regeventday’][‘#view’]

$node->content[‘field_regeventday’][0][‘value’]

$node->content[‘field_regeventday’][0][‘view’]

all don’t really work. I’m not entirely sure why they don’t work. Maybe i’ve got the path of the field reference wrong but the only one I managed to get working is

$node->field_regeventday[0][‘view’];

the first part is referenced by object then continues on with array. Why are all the CCKs wrapped in a [0] tho?

Hi Bobby,

Yeah, it’s a bit of a pick-and-choose situation…

Presumably the [0] is added because Drupal is automatically allowing for many child items for the CCK fields.

EG:
$node->field_regeventday[0][‘view’];
$node->field_regeventday[1][‘view’];

Whether this ever happens in practice, I’m not sure.

Paul

Hi there,

can you help me please, i am new for drupal and i want to design my own custom module. Now i have problem creating my node-modulename.tpl.php file. I know it is for appearance of my new page look but to code it, I don’t know where to start.

thanks for your help.

I created a nodetype that only admin can access so I don’t do a lot of input checking, but this lets me quickly check any node. You’ll want to replace the form action to point to the node where you put this code.

<?php
$displaynode = $_GET['displaynode'];
if( isset($displaynode)){
$fpNode = node_load($displaynode);
print '

';
print_r($fpNode);
print '

‘;

}

?>

The following html form was stripped from my post above. I’ve left out the brackets.

form action=”/node/2855″ method=”get”
input type=”text” name=”displaynode” /
input type=”submit” value=”Submit” /

/form

+1 Uber helpful post

Thanks!!

Guys, install the devel module and then use dsm($node) instead of print_r($node)

Gives you a very nicely formatted, clickable array display that appears within the page in the messages area.

Great tip Oliver

I spent an hour with print_r($node) trying to figure out the correct path for a field value. dsm($node) gave it to me in a minute!

Leave a comment

Archives