Creating custom regions in Drupal themes
Other Drupal articles
A lot of people in the Drupal world have been asking about how to create custom themes beyond the traditional 2 or 3 column layout with a header above and a footer below. The tip below applies to Drupal 6.
Standard Drupal Themes
Most Drupal themes have a number of pre-defined regions that you can use in your templates - $header, $footer, $left, $right and $content. Within your theme, you will do something like this in your page.tpl.php file to render the relevant region on the web page:
<?php if ($left): ?>
<div id="sidebar-left" class="sidebar">
<?php print $left ?>
</div>
<?php endif; ?>
The example above outputs the content of all blocks that have been mapped by the administrator to the left sidebar region.
Great so far, but what if you want do something a bit more creative with your web site? For example, if you ran an online newspaper with a leading feature article section and sub-sections for sports, education and finance, you would find the $left, $right, $content model pretty limiting.
External resources for this article:
Of course, you could use the excellent panels module for Drupal but at the time of writing, this isn’t released for Drupal 6 yet, it’s pretty complex and like many developers, myself included, you may want to have complete control over the layout of your site and the number of div wrappers.
The solution
The solution is actually very simple but like many things, not obvious unless you know. It’s not even clearly documented in the comprehensive and excellent Pro Drupal Development book by John VanDyk.
Here’s what you do.
In your theme’s .info file, include the following section:
regions[left] = Left Sidebar
regions[right] = Right Sidebar
regions[content] = Content
regions[header] = Header
regions[footer] = Footer
This just repeats the standard region types available in all themes. Now, add lines like this:
regions[sportsnews] = Sports News
regions[financenews] = Finance News
Go into the Drupal admin system and view the blocks page (admin -> site building -> blocks). You should see your new regions listed and available for you to add blocks into. If you don’t you may need to refresh your theme by going to the admin -> site building -> themes page and saving the configuration.
Now, you can add blocks to these new regions and they can be rendered on your site by simply including them in your page.tpl.php file like this:
<div>
Sport news blocks here...
<?php print $sportsnews ?>
</div>
<div>
Finance news here...
<?php print $financenews ?>
</div>
Easy?! You now have complete control over the layout of your page, the naming of the regions and the content that is displayed in these regions. We combine this technique along with the Views Module to create new view based blocks.
In the newspaper example above, we would create a new block type view called ‘Sports News’ based on Nodes but filtered by a custom Taxonomy we created called ‘Sports’. We’d then map this block to the ‘Sports News’ region we created earlier.
I hope Drupal developers find this post useful. If I haven’t made anything clear, please post a comment and I will do all I can to help.
























[...] Creating custom regions in Drupal themes In the newspaper example above, we would create a new block type view called
Pingback by sports news | Digg.com — November 30, 2008 @ 6:08 pm
How to position the custom block ( say to the right of the page ) ?
Comment by shubha — December 2, 2008 @ 6:39 am
Hi Shubha,
Positioning of the regions is just standard html and css. All you need to do is create a page.tpl.php and a related css file that determines your layout.
So, in the example above, something along these lines:
<div id="sportsnews">
Sport news blocks here...
<?php print $sportsnews ?>
</div>
<div id="financenews">
Finance news here...
<?php print $financenews ?>
</div>
Then you set up the css for the id’s ’sportsnews’ and ‘financenews’ as usual - either float them or position them using css.
Comment by Webopius — December 2, 2008 @ 7:17 am
this solution is not working.
Comment by indresh — February 2, 2009 @ 9:52 am
Hi Indresh,
Thanks for the comment and sorry that you are unable to get it working. Let’s see if I can walk you through an example.
Step 1. Copy the Bluemarine theme /themes/bluemarine and save it to your /sites/all/themes directory with another name, such as ‘mymarine’. Also rename bluemarine.info as mymarine.info.
Step 2. Now edit the mymarine.info file and add the following lines:
; Custom regions
regions[left] = Left Sidebar
regions[right] = Right Sidebar
regions[content] = Content
regions[header] = Header
regions[footer] = Footer
regions[indresh] = Indresh region
(Notice the custom region at the bottom of the list?)
Step 3. Now, in your admin screen: /admin/build/themes, enable the ‘mymarine’ theme.
Step 4. Go to the blocks admin page: /admin/build/block. If all is well, you will see the additional ‘indresh region’ available in the region menus (the ones that usually say ‘Left sidebar’ as a default).
If this doesnt work, try disabling the theme, then re-enabling it to force Drupal to pick up the changes to the .info file.
Step 5. Now the new region is available, you can use it in your theme templates with a print statement: print $indresh
Adam
Comment by Webopius — February 2, 2009 @ 12:07 pm
If I wish to divide the contents region further into 3 columns, say each column is for a type of news, how to do that?
Comment by Katte — February 11, 2009 @ 9:27 am
Hi Katte,
When I’ve done this, I stop using the $content region and create my own custom regions (for example $news1, $news2, $news3) within my theme templates. Then I’ve written a custom module that retrieves specific news types from the database (e.g. Sports news, Finance news etc).
Within the admin/blocks page, I then map the module’s output to the custom region.
For example ‘Sports News’ from the module goes into $news1.
If you create custom regions in your theme you should also be able to use the Views module to achieve the same result.
Comment by Webopius — February 11, 2009 @ 1:30 pm
Hiya, I just want to say a SERIOUS Thanx for this article! I’ve been looking for ages for a good tutorial on how to make regions, & the related divs for styling.
Your article just covered it all, & best of all, you’re to the point - quick & simple!
Thanx!!!
^_^
Comment by SiNGH — April 22, 2009 @ 10:09 pm
how about collapsible regions?
personally it makes more sense to me to have each(or most) regions to be split up 3 parts. left normal and right
if you do not use one or two of them then they should collapse
i have seen it in Rooplethemes (roopletheme.com) themes
but i have a lot of regions in .info /template.php
so is there a easy way ?
Comment by Kit — April 29, 2009 @ 4:18 pm
Your tutorial is definitely what I was looking for but the implementation i am looking for is a bit different. I am using a different theme, Vitzo. So in my page.tpl.php I have :
…
…
…
and my custom region is
If I print this custom region before and after $content or $breadcrumb, it works fine as you have illustrated. Like I get my Crousel block either at top of page or before or after Content.
However, In my node-XYZ.tpl.php file where I want to print this Crousel region, I am not outputting
but a bunch of different CCK-fields as follows.
…
etc1;
?>
etc2;
?>
etc3;
?>
etc4;
?>
…
I want this custom region to be printed between etc1 and etc2 fields. I have tried
between etc1 and etc2in my node-XYZ.tpl.php but no luck. Do you have any suggestion how should I take care of this.
(sorry if i confused you)
Comment by Nabil — September 2, 2009 @ 5:40 pm
oops forgot to put code snippets…
I am using a different theme than default Garland, Vitzo. So in my page.tpl.php I have :
…
…
…
and my custom region is
If I print this custom region before and after $content or $breadcrumb, it works fine as you have illustrated. Like I get my Crousel block either at top of page or before or after the Content region.
However, In my node-XYZ.tpl.php I am outputting CCK fields individually rather than printing everything in $content.
Instead of
I have a bunch of different CCK-fields (etc1, etc2, etc3, etc4) as follows.
…
etc1; ?>
etc2; ?>
etc3; ?>
etc4; ?>
…
each with individual CSS divs and styling.
I want this custom region to be printed between etc1 and etc2 fields so that it satisfy my website look, you know like a nice intro followed my images then body and so on. I have tried
between etc1 and etc2in my node-XYZ.tpl.php but no luck (and i am assuming it wont because this piece of code should go only in page.tpl.php). Do you have any suggestion how should I take care of this.
p.s. in this carousel region I am trying to print jcarousel_block for images.
Comment by Nabil — September 10, 2009 @ 7:22 am
ok why it is not printing my php code?
here is the link to original question…
http://drupal.org/node/573444
Comment by Nabil — September 10, 2009 @ 7:28 am
Solution: View my answer at http://drupal.org/node/573444#comment-2029290
Comment by Nabil — September 11, 2009 @ 2:01 am