Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Drupal 6 Displaying a block multiple times on the same page or in different regions

Parent Feed: 

There are some times in Drupal 6 where you push the limits of what the blocks interface can do. If you need to display the same block, multiple times on the same page, you will start to see these limitations. An example of where this is useful is a Newsletter signup form. Sometimes a client may want a newsletter signup form to be in the footer of every page, but also displayed more prominently on the contact form page.

You will also run into this issue if you want to output a block in one region on one page and another region on a separate page. An example of this would be to display the newsletter signup form in the header on the front page, but in the footer on every other page of the site.

Both of these examples can easily be achieved using something like Panels or Display Suite, but if you want to stick to the blocks interface, here is a simple way you can solve this by building a custom Drupal 6 module.

The first step is to create a simple Drupal 6 module. After you have the module created, we need to create our own Drupal 6 block. Drop the following code in your .module file. You will need to replace the module name with the name of your module. You will also need to look through the other code replacing text and descriptions as necessary. In my example I will be going through creating a second block for the Drupal 6 Constant Contact module.

/**
 * Implements hook_block().
 */
function MYMODULE_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0] = array('info' => t('Constant Contact Block 2'));
 
    return $blocks;
  }
  else if ($op == 'view') {
    switch ($delta) {
      case 0:
        // Your module will need to define this function to render the block.
        $block = array(
          'subject' => t('Title of block #1'), 
          'content' => '',
        );
        break;
    }
    return $block;
  }
}

The next step is to identify the block you want to display. The best way to do this is to figure out which module you need to duplicate the block for. In my example this was the Constant Contact module. Open up the .module file for whichever module you want to duplicate the block for.

Once you have the module file opened, do a search for "_block" or "hook_block". This should get us to the function that has all the details you need to insert the line of code that will print this block. We need to get the module name and the delta value for our block. Here is an example from the constant_contact.module file's hook_block implementation.

/**
 * Enables us to place a signup form into a block
 */
function constant_contact_block($op = 'view', $delta = 0, $edit = array())
{
	switch($op) {
		case 'list':
			$blocks[0] = array(
				'info' => t('Constant Contact Signup Form'),
				'visibility'      => 0,
				'roles'      => array(1),
				'pages'      => 'user*',
			);
		return $blocks;
		case 'configure':
			$form = array();
		return;
		case 'save':
		return;
		case 'view':
			switch ($delta) {
				case 0:
					$block['subject'] = t('Signup');
					$block['content'] = drupal_get_form('constant_contact_signup_form');
				break;
			}
		return $block;
	}
}

I can pull out the module name from the function constant_contact_block and get that "constant_contact" is the module name. You can also take this from whatever is in front of the .module in the constant_contact.module file name.

The next step is to pull out the delta value for the block. This is displayed below the switch ($delta) { line of code. In this "case" we want the number "0". This is pulled from the case 0: line of code. Blocks may have multiple of these case statements, you will need to find the right delta value for the block you want to display. Many times in a Drupal 6 hook_block implementation this will simply be 0.

We now add the following line of code to our modules hook_block function.

$block = module_invoke('MYMODULE', 'block', 'view', [DELTA]);

We replace MyMODULE with the module name, in this case "constant_contact" and we replace [DELTA] with the delta value, in this case 0. Here is what the finished line of code looks like:

$block = module_invoke('constant_contact', 'block', 'view', 0);

You then need to replace this line of code with what would normally be your Drupal 6 block output code. The final version of your Drupal block code should look something like this:

/**
 * Implements hook_block().
 */
function MYMODULE_tweaks_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0] = array('info' => t('Constant Contact Block 2'));
 
    return $blocks;
  }
  else if ($op == 'view') {
    switch ($delta) {
      case 0:
        $block = module_invoke('constant_contact', 'block', 'view', 0);
        break;
    }
    return $block;
  }
}

You can now add this block just like you would any other block. It should be an exact duplicate of the other Drupal block.

A couple notes: This approach still has it's limitations so a better solution is using something like Panels or Display Suite. However it works well for one off simple fixes on sites that are already making heavy use of blocks. Also note that if you are displaying the same block multiple times on the same page, everything should work fine, but your CSS may not validate if the block uses the same CSS ID since it will now be in multiple places inside the HTML.

Hope that helps and let me know if you have any questions.

Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web