How to add a block region to a node page in Drupal 6


As a Drupal themers / front end developers, we are always asked to push the envelope of what's possible with design and theming. With Drupal 6, custom block regions are usually added in page.tpl.php which is normally outside of the actual page node content / comments. It would be above, below content or in sidebars typically. Occasionally you have the need to add a block region within a node area. This comes in handy especially if you are using a custom themed node page that uses CCK fields, e.g., "node-[custom_content_type].tpl.php".  To accomplish this there are a few steps involved.

How to add a block region to a node page in Drupal 6

  1. Determine and add code to the node type you will add it to in your theme. It might be simply node.tpl.php or a custom named node as mentioned above.
  2. Add a preproccess node function to your theme's template.php
  3. Add the new region your theme's .info file
  4. Flush your site cache
  5. Test it out either using context or the actual block page assigning an existing or new block to the new block region

First we need to determine the name of the new block region that we are going to add. In this tutorial we will call it "node_message". In the node page you want to add code to determine where in the page you want to add it. This part is just like adding a regular block region to page.tpl.php. In our example node.tpl.php, we will add the new code after the $content and post meta variables. Note that your node or custom node template file may vary but this will give you an idea of what's possible. Here is code near the bottom of node.tpl.php.

<div class="content">
  <?php print $content ?>
</div>

<?php if ($links): ?>
   <div class="postmeta"><?php print $links; ?></div>
  <?php endif; ?>
</div>

We now insert our new "node_message" block code at the end. Note that you could also wrap a custom div class for the new code as well as illustrated in our example. This new block region should not already be in page.tpl.php as you do not want the region to load and process twice so it should be unique to the node.tpl.php level.

 <div class="content">
    <?php print $content ?>
  </div>

<?php if ($links): ?>
    <div class="postmeta"><?php print $links; ?></div>
  <?php endif; ?>
</div>

 <?php if ($node_message): ?>
     <div class="node-message"><?php print $node_message; ?></div>
<?php endif; ?>

Now we need to tell Drupal how to process this new code so we will go ahead and add our preprocess function to our theme's template.php file. Note if your theme does not have this file you can go ahead and create it. If it is a new template file with nothing else added you need to add an opening <?php tag but not a closing one. If you are adding to an existing template.php file with existing code, then it's not necessary to add the opening <?php tag.

<?php
function my_theme_name_preprocess_node(&$vars, $hook) {
  $vars['node_message'] = theme('blocks', 'node_message');
}

Note above that "my_theme_name" should be the actual name of your theme so you will need to replace that as well as 'node_message' which is the custom name of your block if you decide to change the name.

The next part entails adding the new block region to your theme's .info file. You can do something like this:

regions[node_message] = Node Message

Again take care in the name, it must reflect the actual name of your block, i.e. 'node_message'. Now we are at a point where you can go ahead and clear your site cache and assign or create a new block on the /admin/build/block page. The new custom 'node_message' region should show up on in the regions drop down menu on this page. If you have Drupal's Context module installed, you can also assign your block to the newly created region using that.

Update

An interesting conversation transpired on Twitter after I posted a link to this blog post: Twitter Conversation

Amy Stephen (@AmyStephen) suggested that this tutorial was similar to using {loadmodules positionname} in Joomla & Steve Burge (@alledia) suggested you could use the Drupal module, Insert Block. This method while similar is more of a one off type implementation for single pages.

What this tutorial does is show you programmatically how to add a block within a node that can be leveraged globally. In a way the Insert Block module is more granular where you can literally insert a block between two paragraphs. The method described in this blog post would be ideal for example of having a block on 50 different pages between two specific CCK fields in a custom themed node which you could simply set with one Context instance.

In the screen capture below you can click to enlarge and see an example of a custom block added within a node. I hope this tutorial has been helpful, feel free to comment with any feedback or issues. This tutorial was inspired by a post on drupal.org: http://drupal.org/node/361209

Tags