Jump to Navigation

Drupal 6 - How to embed a region in a node

Image to accompany story

There will come a time when you'll want to add a new region to your Drupal theme, weather you are using a stock theme, a modification of a base theme such as Zen (like me) or creating your own theme from scratch.

Drupal 6 makes the creation of new regions as simple as adding one line of code to your themes template.php file. However, by default new regions created in this manor will only be available to your themes page template (page.tpl.php) and a little extra work will be needed if you want to display it somewhere else.

For the purposes of this article, lets say that we want to add a new region at the top of all story nodes for displaying some google adsense adverts. But, we only want the region to be displaed if we are in the full node view and not in teaser mode.

Add the region to your themes .info file

First thing to do is to define the new region. So, open up your themes .info file (it should be named yourtheme.info) and look for the lines which define the regions. In the Zen theme, these lines look like this:

regions[left]           = left sidebar
regions[right]          = right sidebar
regions[navbar]         = navigation bar
regions[content_top]    = content top
regions[content_bottom] = content bottom
regions[header]         = header
regions[footer]         = footer
regions[closure_region] = closure

The name in the square brackets is the name of the variable that will be made available to your templates. The text after the equals sign is a just descriptive text that will be used on the admin/build/blocks page. Choose a name which reflects what the region will be used for so you can easily identify it later - I chose the name node_advert_top which will make a variable named $node_top_advert available to my templates. To add the new region, simply add a new line under the existing region declarations.

...
regions[footer]         = footer
regions[closure_region] = closure
regions[node_advert_top]= node advert top

Expose the region variable to your node template file.

By default, region variables are available for use in your page template file (page.tlp.php

). However, we want to display our advertisements block within the actuall node itself so we need to add the new region variable $node_advert_top to the node.tlp.php file. To do this we can use the preprocess_node() function. Open up your template.php file, create a function named yourtheme_preprocess_node() and add your new region to the $vars variable.

function kirkdesigns_preprocess_node(&$vars, $hook) {
  $vars['node_advert_top'] = theme('blocks', 'node_advert_top');
}

Place the region where you want it.

Now you just need to open up your node template file (node.tlp.php) and add the region where you would like it to appear. Remember though, I only want to display this advert block on story nodes, and I only want it to be displayed if we are viewing the full article. The first if statement does exactly that.

<?php if ($node_advert_top && !$teaser && $node->type == 'story'): ?>
  <div id="node-advert-top" class="region region-node_advert_top">
    <?php print $node_advert_top; ?>
  </div> <!-- /#node-advert-top -->
<?php endif; ?>

Comments

Anonymous's picture

Thanks for this article. I saw another function function that also works.

phptemplate_preprocess_node(&$vars) {
  if (!$vars['teaser']){
    foreach (array('belowPost') as $region) {
      $vars[$region] = theme('blocks', $region);
    }
  }
}

Check http://drupal.org/node/237391#comment-784315 any difference?

tom's picture

Yes, that would work too. The only difference is that you're testing for the teaser variable in template.php rather than in the node template itself - I think that really comes down to personal preference, but I prefer to do this kind of filtering in node.tlp.php because it makes the template easier to read (I don't need to refer back to template.php to see when the region is available).

Also, if you're only adding one region there is no need to create and array and loop through it, so you could probably change:

foreach (array('belowPost') as $region) {
  $vars[$region] = theme('blocks', $region);
}

to just:

$vars['belowPost'] = theme('blocks', 'belowPost');
Anonymous's picture

Great article!!!!!!!!! Thanx.

Anonymous's picture

Thank you very much! I've been fighting with Drupal for the whole day until I found your post.

Anonymous's picture

thank you seriously.
hotmail email

Anonymous's picture

Hi there,

Sorry, if I'm saying something stupid! I'm very new in Drupal - its my first project.

I'm using the multiflex3 theme on Drupal 5. I've created my frontpage using views, mini-panels and panelpage (its basically a panel page containing a few mini-panels and views). I did not use the theme's right-sidebar rather I sliced my panel-page to have a fixed-sized right column to display the adverts. So far it works fine. If interested, you can see the test site here http://portal.ukbengali.com (it's in Bengali!)

But in the node page (when any node is clicked) the right column disappears, but I want a side bar to appear on the node pages as well and put an specific view there. If I enable the theme's right sidebar (to be displayed on the Node page) it ruins my front-page layout as well.

Any solution? I really appreciate your article and would be grateful if you could help me out.

Cheers
- Arif

Anonymous's picture

This article help me out a lot! Thanks, man.

Anonymous's picture

That code will be usefull for me as well.

Anonymous's picture

I chose the name node_advert_top which will make a variable named $node_top_advert available to my templates.

should it not be

node_advert_top which will make a variable named $node_advert_top

Anonymous's picture

your code only display it in "story" type,
1. How to set the region for all type to display?
2. How to set the region for type "story" and "blog" only?

thanks!

tom's picture

You just need to add an extra condition...

<?php if ($node_advert_top && !$teaser && ($node->type == 'story' || $node->type == 'blog')): ?>
  <div id="node-advert-top" class="region region-node_advert_top">
    <?php print $node_advert_top; ?>
  </div> <!-- /#node-advert-top -->
<?php endif; ?>

Or,if you want it to display on all node types, remove the $node->type check completely.

Anonymous's picture

Or,if you want it to display on all node types, remove the $node->type check completely.

Anonymous's picture

Hi There
How would you go about adding multiple regions? I've got 5 I need to add. Plus I can't get even one region to show now. Here's what I'm using:

<?php if ($bottom_left): ?>

<?php print $bottom_left ?>

<?php endif; ?>


function slarc_preprocess_node (&$vars, $hook) {
$vars['bottom_left'] = theme('blocks', 'bottom_left');
}

My regions are properly defined as well.

Anonymous's picture

nm, got it working :-)

Anonymous's picture

What i would like to know that is there any way from where we can administer the nodes from the admin section.I may sound naive but i am new to drupal and any help will be appreciated as many of my clients are thinking of moving to drupal for the variety of resources it provides.I am a website developer and i am generllay working in miami web design
I would also love to know if i could get help from the owner of this website on some other petty issues as well.
Thnx
Jammy

Anonymous's picture

How would you get it to appear partway into the content area of the node--say, floating left of the second paragraph?

I've seen a few tutorials on this for Drupal 5, but nothing that works for 6.

Anonymous's picture

Excellent article; one quick emendation --
node.tlp.php
should read
node.tpl.php

- zJ

Anonymous's picture

same in the node page (when any node is clicked) the right column disappears, but I want a side bar to appear on the node pages as well and put an specific view there. If I enable the theme's right sidebar (to be displayed on the Node page) it ruins my front-page layout as well.

Anonymous's picture

doesnt work for me
everything is done the same here explained.

page.tpl renders the added region nicly but the in node.tpl nothing appears. Like node.tpl doesnt understands what print($region_name) etc ... means!!! I can change any html code in node.tpl and they appear as soon as upload and refresh my drupal page.

but no region is rendered in node!!! help please. what could cause that odd functionality?

Anonymous's picture

Thanks , nice solution online casinos

Anonymous's picture

same in the node page the right column disappears, and I want a side bar to appear on the node pages as well and put an specific view there. Thanks

Anonymous's picture

Thanks for this post, saved me a heap of time messing around with regions.

- Sean Bannister

Anonymous's picture

Good idea. I also know when you can create a view you can have it make a 'block' so maybe I can work thru that. I was just hoping to learn the programmatic way to have php call blocks instead of views in the example above. Time to learn more. Thanks to all, if anyone has any other ideas Id love it.

Anonymous's picture

Thanks for this post. How can I make the visibility of this region in the teaser, if the material does not contain any further (without "Read More" Link)?

Anonymous's picture

This was very useful, thank you!

Anonymous's picture

Fatal error: Cannot redeclare newswire_preprocess_node() (previously declared in C:\xampp\htdocs\themes\newswire\template.php:116) in C:\xampp\htdocs\themes\newswire\template.php on line 233

I did the same things as you explained. it gives error like above. what should i do?

my theme is newswire.

tom's picture

Hi Kcy,

It sounds like your theme (newswire) already uses the preprocess_node() function. So, rather than creating your own function you should find the existing one and edit it. Look around line 116 in themes/newswire/template.php and you should find the existing newswire_preprocess_node() function. Then, simply add the following code to the end of that function:

$vars['node_advert_top'] = theme('blocks', 'node_advert_top');

Please share your thoughts, comments and suggestions...

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account, used to display your avatar.
If you have your own website, enter its address here and we will link to it for you. (please include http://).
eg. http://www.kirkdesigns.co.uk