Community Documentation

Theming blocks individually, by region, or by module

Last updated August 27, 2009. Created by joachim on December 20, 2006.
Edited by bekasu, VM, Jeff Burnz, add1sun. Log in to edit this page.

Designers can create multiple tpl.php files for blocks based on the specific block, the module that created the block, or the region that the block appears in.

Template files are searched in the following order:

  • block-[module]-[delta].tpl.php
  • block-[module].tpl.php
  • block-[region].tpl.php
  • block.tpl.php

For example, the user login block has a delta of '0'. If you put it in the left sidebar, when it's rendered, PHPTemplate will search for the following templates in descending order:

  • block-user-0.tpl.php
  • block-user.tpl.php
  • block-left.tpl.php
  • block.tpl.php

You can find the block's module and delta by looking at the html source of a page: each block's main DIV has the following classes and IDs:

<div class="block block-{module}" id="block-{module}-{delta}"> 

Note that custom blocks created in the admin UI count as coming from block.module, so their template is 'block-block-[delta]'.

Styling with CSS

These classes and IDs also let you apply CSS rules to blocks selectively: all blocks, all blocks from a particular module, or just one block. (To style blocks by region, use the DIV that wraps an entire region in your selector.)

Note that the delta is usually a number: each module numbers the blocks it provides, starting at 0. In some cases, the delta can also be a name: eg to style blocks created with the Views module, use block-views-[name of your block].tpl.php.

Comments

Need a prime block.tpl.php also

I found that
block-[module].tpl.php
did not take effect unless there was also a custom (copy of)
block.tpl.php
in the theme dir also. It may have just been Zen template that does odd things with template suggestions.

Also, the module part of the filename is verbatim - using underscores not dashes, so for local_menu.module it's
block-local_menu.tpl.php
which is a little inconsistent, but makes sense.

.dan.
if you are asking a question you think should be documented, please provide a link to the handbook where you think the answer should be found.
| http://www.coders.co.nz/ |

you are right

i also had to copy block.tpl.php from genesis to its sub theme for this to work, i guess this applies to all starter themes.

Thanks for the hint, I

Thanks for the hint, I wondered why it didn´t work. Now everything´s fine. :)

tpl.php into module folder?

How about when you would want to place the tpl in the module folder instead of the theme folder? Does anyone know how to let the theme engine know?

Joel Box - Mondial-IT

hook_theme

See the module/theme developer guide and the docs on hook_theme.
But best to first look at EXAMPLES from any module you see that has some tpl.php files distributed in its module dir, then look at that modules hook_theme(), then look at the API docs again to understand how it does what it does.

And remember to flush the theme registry regularly when making changes to this stuff. It's aggressively and frustratingly cached.

theme and theme_blocks

I wanted to "theme" the blocks in a region in a way where certain blocks had HTML wrapped around them and then others were outside it. I figured I could hack a solution by adding a token and str_replacing for it, hard coding the blocks into fixed positions, or creating a subregion that divided one region into two. Each of these approaches has a drawback and doesn't scale well or adapt to other Web sites and future projects.

After looking around and thinking about this for a while I stumbled across template_preprocess_page (Drupal 6 API). This is the function that defines many of the variables we use in the page templates (e.g. page.tpl.php or page-type.tpl.php). Finding this function answered the question I was on a miserable search to answer, "what part of Drupal concatenates all of the blocks in a region and may I theme it?"

The answer is theme and theme_blocks. My theme's name is Framework and this is the code I was able to use to accomplish this, it is added to my template.php file:

<?php
 
//Group blocks in regions
 
function framework_blocks( $region )
  {
   
//Define a string to concatenate the markup too
   
$html = '';

   
//Define an array of regions that need individual treatment
   
$custom = array( 'left' );

   
//Try to create an array of block names in this region
   
if( $blocks = block_list( $region ) )
    {
     
//Process all the blocks that are in a custom region differently
     
if( in_array( $region, $custom ) )
      {
       
//Group certain blocks in the left region
       
if( $region == 'left' )
        {
         
//Loop through the blocks and theme them individually
         
foreach( $blocks as $key => $block )
          {
           
//Create a shorthand reference to the block's name/unique identifier
           
$name = $block->module . '-' . $block->delta;

           
//Theme the block and concatenate the markup
           
$html .= theme( 'block', $block );
          }

         
//Remove the block list from memory
         
unset( $blocks );
        }
      }
    }

   
//Default; if the block list still exists process it regularly
   
if( isset( $blocks ) )
    {
     
//Loop through the blocks and theme them individually
     
foreach( $blocks as $key => $block )
      {
       
$html .= theme( 'block', $block );
      }
    }

   
// Add any content assigned to this region through drupal_set_content() calls.
   
$html .= drupal_get_content($region);

   
//Return any markup generated
   
return( $html );
  }
?>

This code overrides theme_blocks, defines an array of regions that need custom handling, checks if the supplied argument is one of those regions, if it is then it checks which one and provides an area to customize it, if it isn't one of those regions it treats it normally and doesn't change anything. If you read this code you'll notice that it doesn't actually do anything different. In the end I figured out how to do what I wanted another way.

My name is Sean Ruiz and I am a Web Developer for SEO Inc..