Creating Dynamic Tabbed Regions in Drupal

Building websites that are content-rich often means creating a user interface that displays lots of content on a single page. Sometimes it's hard to fit it all. Many designers turn to tabs to fit in all the content. In Drupal, there are several ways to implement tabs.

Many sites use the quicktabs module to build special tabbed blocks out of nodes, blocks, or views. This is great for sites that need tabbed blocks for sidebars or the homepage. However, quicktabs requires that you manage quicktabs blocks using a separate interface, and can become a problem if the blocks that show up on a given page vary depending on context. A solution we developed for the McGill University Health Centre website was to use the tabs module to turn all the blocks in a given region into a set of tabs.

We added a small custom module called tabbed_region, which takes the "fancy_tabs" region from the theme and renders all the blocks in the region as tabs. Here's the contents of tabbed_region.module:

<?php

function tabbed_region_preprocess_page(&$vars) {
  
$vars['fancy_tabs'] = tabbed_region_blocks('fancy_tabs');
 
  
//We re-define the styles, because drupal_add_css() in tabs_load() runs too late
  
if ($vars['fancy_tabs']) {
    
drupal_add_css(drupal_get_path('module''tabbed_region') . '/tabbed-region.css');
    
// See theme.inc hook_preprocess_page()
    
$vars['style'] = drupal_get_css();
    
$vars['css'] = drupal_add_css();
    
$vars['scripts'] = drupal_get_js();
  }
}

function 

tabbed_region_blocks($region) {
  
$output '';
  if (
$list block_list($region)) {
    
$tabsform['tab'] = array('#type' => 'tabset');
      foreach (
$list as $key => $block) {
      
$tabsform['tab'][$key] = array(
         
'#type' => 'tabpage',
         
'#title' => $block->subject,
         
'#title' => $block->content,
      );
    }

   

$output tabs_render($tabsform);
  }
  return 
$output;
}
?>

Other than this bit of PHP, the module contains a CSS file which changes the look of the tabset from the default Drupal tabs to the tabs in the image above. Of course, you could add whatever CSS you need to make your tabs look the way you want.

Issues

Note that if you're using the Context module you might have to call context_list_blocks instead of list_blocks from the tabbed_region_blocks function. However, I believe this is fixed in the most recent version of Context since there is no longer a context_list_block function.

One issue that I've come across is that the block_list function doesn't always return blocks in a predictable order. Generally, it returns them according to weight, but in certain cases a

Contributing Back

I'm currently working on converting this custom code into a contributed module. So far, the contributed version would allow the user to specify from the admin interface which region should display blocks in as tabs.

Comments

There is a typo I think

$tabsform['tab'][$key] = array(
'#type' => 'tabpage',
'#title' => $block->subject,
'#title' => $block->content,
);

should be

$tabsform['tab'][$key] = array(
'#type' => 'tabpage',
'#title' => $block->subject,
'#content' => $block->content,
);

Thanks for this. Very elegant solution.