Need some help with your project? Contact me

How to programatically add a region to your theme in Drupal

The conventional way of adding a new region to your theme in Drupal 7 is by editing the .info file and declaring it in there. However, there are ways you can achieve similar effects dynamically - from a custom module.

As you know, declaring a region in the theme’s .info file is not always useful: you have to manually declare it and it's not a useful way if you are writing a module that needs to dynamically create new regions. Enter hook_system_info_alter().

This Drupal hook takes three arguments(&$info, $file, $type) and alters the data transmitted to Drupal from both theme and module .info files. So in order to make Drupal register another region from your .module file, you would write something like this:

/*
 * Implements hook_system_info_alter().
 */
function your_module_name_system_info_alter(&$info, $file, $type) {
  if ($type == 'theme') {
    $info['regions']['region_machine_name'] = t('Region name');
  }
}

You need to make the following word replacements though:

  • your_module_name = The machine readable name of your module;
  • region_machine_name = The machine name of your region

This function will check that the type it targets to alter is a theme (not a module) and alters the $info variable by adding a new region - with its readable and machine names. But remember, for this to take effect, the caches need to be cleared. So if you intend to use this dynamically, don’t forget the existence of this functions: cache_clear_all();

OK, so hope this helps. Let me know if you run into some problems.

Some related articles you might enjoy

Comments

Thanks I didn't know that :)

Regions module also provides a nice little structure/api for doing this quickly, worth at least a look. drupal.org/project/regions

I'm struggling to see a use-case for this. Is there an advantage to using this over adding it to the theme's .info file?

Why would someone want to do that? Can you provide a use case?

I appreciate being informed about such a useful hook I had previously overlooked. I usually do this via the info file.

While you mention cache_clear_all() ... for a Live site with huge amounts of content would it be valuable to specify a better example for clearing the cache, something like:


// Possibly target just your theme_name as well ...
cache_clear_all('theme_registry:*', 'cache', TRUE);

calling just cache_clear_all() would likely wipe the page and block cache as well -- which could be bad.

Thanks for the comments!

@btopro, I will definitely check it out!
@Craig, there can be cases in which you need to generate new regions for a particular module you are writing. I did it and saw other modules that do it.
@tenken, good point!

Thanks!

D

I don't think this is useful. Because while debugging or working with themes, you do not have control over programmatically created regions.

Programatically creating a new region does not mean you place it in a theme. It gets created for you to use it however you want.

There are modules that create new regions to be used dynamically by it without interfering with the theme layer.

Thanks for the comment.

This is good info and a very useful hook, but is there a way to make Drupal using this hook to add the page render code in a theme template like page.tpl.php for example?

Hey there,
Once you declared the new region with this hook, you can use the block_get_blocks_by_region() function in a template preprocess function to return and store it into a variable to have it available to print in the tpl file.

Thanks for your quick reply, but:

  1. How would using block_get_blocks_by_region() tell Drupal exactly WHERE in the template to place that block region?

  2. How is this different from adding print render($page['REGION-NAME']) to a .tpl file?

Thanks,
Bruce

Hey there,

Seems you are trying to do things wrong. If you want a new region in your theme, just declare it in the theme .info file and then print it in the template file like usual. If you need the region in a module and then print it within the framework of the module (not theme), you can use this hook: hook_system_info_alter() to declare it and have it available.

But if I use hook_system_into_alter(), how does Drupal know exactly where I want that block region to print?

You don't use this hook to print the region, you are using it to hook into the Drupal system info and add new stuff what is loaded from the .info file. You just basically declare a new region with this hook.

Then you can do what you want with it in your module. Check out Block Inject to see how it's used there.

Just like this $reg = block_get_blocks_by_region(<region_machine_name>);
$reg_markup = render($reg);

print $reg_markup;

So, assuming that you what to add it to a form, you can do something like this
hook_form_name_form($form, &$form_state){
$reg = block_get_blocks_by_region('health_left_panel');
$reg_markup = render($reg);

$form ['markup'] = array(
'#type' => 'markup',
'#markup' => '<div id="form_markup">'.$reg_markup.'</div>'
);

return $form;
}

Thanx for this, but ...
Can you explain some useful scenario with this technique.

Hello,

For example, the Block Group module uses this technique to create corresponding regions to groups of blocks.

Thanks for the comments!

D

Add new comment

You must have Javascript enabled to use this form.