Can regions be printed within a node template, or are regions strictly confined to page templates?
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 Configuration → Development → Performance 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
-
4There'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