Can regions be printed within a node template, or are regions strictly confined to page templates?

up vote 47 down vote accepted

You can print regions inside any template, but they aren't available out of the box in the node.tpl.php template. To make them available, you'll create a new variable for use in your node.tpl.php template that'll contain all the region content.

Creating new template variables is done by using a preprocess function. In your theme's template.php file, create a function that looks like this:

function mytheme_preprocess_node(&$variables) {
}

Replacing mytheme with your theme's short name. Now, in order for Drupal to recognize this new preprocess function, you need to rebuild your site's theme registry. This is as straightforward as going to ConfigurationDevelopmentPerformance and pressing the "Clear all caches" button at the top.

Now, the way preprocess functions work is that $variables contains an array that corresponds to your template's available variables. For example, in node.tpl.php, $submitted contains the author byline. In the preprocess function above, it's found in $variables['submitted'].

To mimick what you have in page.tpl.php, where you have an array called $page that contains all the regions, you'd want to populate $variables['page'].

The problem is that $page in node.tpl.php is already populated with a true/false value that lets you know whether you're looking at the node by itself or in a listing.

So to avoid that name collision, populate $region instead:

function mytheme_preprocess_node(&$variables) {

  // Get a list of all the regions for this theme
  foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) {

    // Get the content for each region and add it to the $region variable
    if ($blocks = block_get_blocks_by_region($region_key)) {
      $variables['region'][$region_key] = $blocks;
    }
    else {
      $variables['region'][$region_key] = array();
    }
  }
}

Then, in your theme's node.tpl.php template, you can render any region by doing the following:

<?php print render($region['sidebar_first']); ?>

Where sidebar_first is the name of the region you want to render.

  • 1
    Finally a working solution for Drupal 7 :) – Eduard Luca May 17 '12 at 14:50
  • 4
    There's also a quick 'n' dirty solution that worked for me <?php print render(block_get_blocks_by_region('machine_name_of_your_region'));?>. From here: webomelette.com/add-region-node-template – Darragh Enright Dec 17 '13 at 12:29
  • This solution is nifty. Could you give examples as to when is it most applicable to print regions within node.tpl.php instead of having it in page.tpl.php? – Randell Mar 2 '14 at 23:12
  • It depends on your design. Sometimes the layout might put the sidebar in a place where it is much easier to theme if it were inside the node div instead of outside of it. – rooby Nov 4 '14 at 1:03
  • Don't forget about appropriate region wrappers! See system_page_alter() for reference. Remember that block_get_blocks_by_region() returns only array of blocks and if you want to render it as a region, you need to add region wrapper. – SiliconMind Apr 16 '15 at 14:09

protected by kiamlaluno Sep 11 '12 at 17:36

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.