How to create a block region for node.tpl.php

Update: appparently, today was the day to write about this. Nedjo Rogers submitted a handbook page that shows a different method of achieving the same end.

For the most part, Drupal 4.7's block system is underutilized. This is a shame; with the proper templating, drupal's block system can become a valuable workhorse. In this tutorial, you will learn:

  1. How to override default functions in the phptemplate.engine
  2. Create new regions to place blocks
  3. Pass a block region into node.tpl.php

By the end of this tutorial, you will have the ability to place blocks into node's like a so:

: cool

As with every tutorial in Extreme PHPtemplate theming, you must be working with drupal 4.7, and some background in PHP. If you have no background in PHP, than I suggest you just play along. You may, god forbid, begin to learn.

Step 1: Override phptemplate_regions() in themes/engines/phptemplate/phptemplate.engine

<?php function phptemplate_regions() { return array( 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer') ); } ?>

Observe the above code. It generates the regions that allow you to place blocks in the header, content, left sidebar, right sidebar, and footer. In order to create our "article blocks" region, we need to first override this default function in template.php. As some of you may have already noted, this function already contains a "phptemplate_" prefix. Obviously, in order to override this function, we therefore cannot use our normal method of adding that prefix. Luckily, the work around is super easy, and intuitive. Simply replace the phptemplate_ prefix with the name of your theme. This tutorials theme is named "xtreme_theming1", thus our template.php file will look like this:

template.php

<?php function xtreme_theming1_regions() { return array( // We'll want to return the default regions 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer'), // !!Here's our new region "article blocks"!! 'article_blocks' => t('article blocks') ); } ?>

Note that this same method can be used to override any function in phptemplate.engine. Thus, phptemplate_comment($comment, $links = 0), becomes xtreme_theming1_comment($comment, $links = 0). And so forth.

Step 2: send the blocks to node.tpl.php

First, Go to administer->blocks, "admin/block". Assuming you followed step one correctly, you have a new region called "article blocks", available to send blocks to. Enable "recent blog entries", and put it into the "article blocks" region.

Second, go to template.php. Call the "theme_blocks($region)" function, and send the output to node.tpl.php. Below is the proper way to do that:

template.php

<?php function _phptemplate_variables($hook, $vars) { /* in this case, a hook refers to the beginning of tpl.php file Thus, case 'page' affects page.tpl.php. 'node' affects node.tpl.php, and case 'block' would affect block.tpl.php */ switch($hook) { case 'node' : /* $vars['article_blocks'] is $article blocks in node.tpl.php */ $vars['article_blocks']= theme_blocks('article_blocks'); break; } return $vars; } ?>

The final step is to print the variable in the node.tpl.php file. I recommend that you place the following code directly above the "node" div

node.tpl.php

<?php /* LOOK! */ if ($article_blocks) { ?> <?php print $article_blocks;?> <?php } ?> <?php if (!$status) { print " node-unpublished"; } ?>"> ...

Now, click save, and see your new node.tpl.php block region in all its glory:

Step Three: Take Care of the Loose Ends

We have two problems. One we don't want to show the article_blocks region, unless you're viewing the entire node. Second, our article block... to be frank.... looks like crap.

Below, we've gone ahead and taken care of problem one by instructing phptemplate to only return "$article_blocks" when $page doesn't equal zero ($page equals zero when you are not view full nodes). Here's the full template.php file for this tutorial below:

<?php function xtreme_theming1_regions() { return array( // We'll want to return the default regions 'left' => t('left sidebar'), 'right' => t('right sidebar'), 'content' => t('content'), 'header' => t('header'), 'footer' => t('footer'), // !!Here's our new region "article blocks"!! 'article_blocks' => t('article blocks') ); } function _phptemplate_variables($hook, $vars) { /* in this case, a hook refers to the beginning of tpl.php file Thus, case 'page' affects page.tpl.php. 'node' affects node.tpl.php, and case 'block' would affect block.tpl.php */ switch($hook) { case 'node' : /* $vars['article_blocks'] is $article blocks in node.tpl.php */ if ($vars['page'] /* the equivolent of $page in node.tpl.php */ != 0) { $vars['article_blocks']= theme_blocks('article_blocks'); } break; } return $vars; } ?>

Extra: The CSS to make it look like it look halfway Decent.

The following CSS rules will make your block look like they do in the opening screenshot:

/* CSS Document */ #article_blocks { float:right; width:300px; font-size:0.9em; border:1px solid #cccccc; margin:0 12px 12px 12px; } #article_blocks .block { width:100%; margin:6px; } #article_blocks ul li { width:100%; }