"Disable Drupal blocks/regions" has no effect with some custom themes

I came across a problem with a panels page when I check the "Disable Drupal blocks/regions" box, the sidebars are supposed to disappear so that the content takes the full width. But it didn't work.

Switching back to Garland and the sidebars disappeared as expected. After a quick search, I found this post on drupal.org which is the same issue but one of the replies essentially says to hack core to get it to work, but that is not necessary.

In Drupal core, it only looks for sidebars named left and right. I have 4 (left_sidebar_primary, left_sidebar_secondary, right_sidebar_primary, right_sidebar_secondary), this allows me to style some blocks easier dependent on their weighting in the sidebars.

The workaround is very simple. All it requires is a few lines in your template.php file in your hook_preprocess_page() function.

If you haven't that function in your template.php file, then here is the necessary code:

<?phpfunction theme_name_preprocess_page(&$vars) {
  // Code goes in here
}?>

The code which we need to enter is fairly simple.

<?phpfunction theme_name_preprocess_page(&$vars) {
  if (!$vars['show_blocks']) {
    $vars['left_primary'] = '';
    $vars['left_secondary'] = '';
    $vars['right_primary'] = '';
    $vars['right_secondary'] = '';
  }
}?>

Here we check to see if the $vars['show_block'] variable is FALSE, if it is then we set the content of all the sidebar regions to nothing.

If you would like to disable more regions, just add them as they are defined in your theme_name.info file.

One other thing to mention is that you need to make sure in your page.tpl.php file that you correctly add the code to not show any HTML markup if the region is empty.

<?php if (!empty($left_primary)): ?>
  <div class="sidebar-primary">
    <?php print $left_primary?>
  </div>
<?php endif; ?>
<?php 
if (!empty($left_secondary)): ?>
  <div class="sidebar-secondary">
    <?php print $left_secondary?>
  </div>
<?php endif; ?>

Comments

[...] This post was mentioned on Twitter by Drupal Planet, SanjeevJain, Drupal Feed, Alex Lindahl, web dev fools and others. web dev fools said: James Tombs: “Disable Drupal blocks/regions” has no effect with some custom themes http://bit.ly/fYG4kh #drupal [...]

This doesn't really look like a great solution. The blocks have already been rendered, you are just not showing them. To get this to work and not suck for performance you'd also need to change your block visibility rules for each block.

Indeed, but those rules could get quite complicated on a technical site. With caching especially with a module like Boost, the fact that the blocks are rendered shouldn't a problem at least past the initial page view.

Ah so if something is cached it's okay to render and then remove the rendered object. But what if these blocks contain a non cached view for example.

Moral of the story, fix things where they should be fixed. And in this case, this is NOT the correct place to fix this. If a block is disabled, it should not go trough the render loop at all.

And that is what is somewhat wrong in the way drupal theme's elements. Drupal themes from the small elements to the big elements. First a Link, then that link is placed in a list, then in a box, then in block then finally in a page. Yet the last layer decides it should not be rendered. To fix this once and for all, theming should be reverted. Starting with the big elements, then the smaller.

It is not ideal, but it is the easiest to implement solution to the problem especially when you have a lot of blocks that you don't want to apply a lot of different visibility rules to. The site I have been using it on has views in the blocks but irregularly updated, so caching isn't a big problem.