Displaying Drupal Context regions in Node templates

Theme regions in Drupal are normally output in the Page template (page.tpl.php) in a format similar to this:

<?php if ($page['sidebar_first']): ?>
   <aside id="sidebar-left" class="<?php print $lsb_size; ?>" role="complementary">
        <?php print render($page['sidebar_first']); ?>
   </aside>
<?php endif; ?>
Where sidebar_first is the region that was defined in the .info file of the theme. However, there are times when we need to place these regions within a template other than the Page template. There is also the situation where the content of these regions is defined by the reaction of a Context. Let's take the Node template as an example (node.tpl.php). I have two regions that I want to live within the node, these regions appears as two columns in the node body. Unfortunately the sidebar_first variable is not available on the Node Template, it's simply out of scope for that file, so we need to find an alternative way of retrieving the context for a region outside of the Page template.

1. Define those regions in your info file

regions[in_content_left] = In Content Left
regions[in_content_right] = In Content Right

2. Create a preprocess hook in template.php

Because we're working with the node template here we'll use template_preprocess_node()
/**
 * Implements template_preprocess_node().
 */
function themename_preprocess_node(&$variables) {
  // Load the blocks for the current context using the block reaction plugin for the current context...
  $reaction = context_get_plugin('reaction', 'block');
  $variables['region']['in_content_left'] = render($reaction->block_get_blocks_by_region('in_content_left'));
  $variables['region']['in_content_right'] = render($reaction->block_get_blocks_by_region('in_content_right'));
}
So what's happening here?
  • First we need to load the context reaction. The context reaction will contain all of the reaction settings of the current page context.
  • Then we retrieve the blocks for the specified region from the context reaction.
  • Finally we render those blocks and assign them to a variable called region which is then available in the node template

3. Output the variable in node template (node.tpl.php)

Now that a variable has been created, all that's left to do is output that variable in the correct place in the node template:
    <?php if ($region['in_content_left'] || $region['in_content_right']): ?>
      <div class="row">
        <div class="six columns">
          <?php print render($region['in_content_left']); ?>
        </div>
        <div class="six columns">
          <?php print render($region['in_content_right']); ?>
        </div>
      </div>
    <?php endif; ?>