7.x block.api.php hook_block_info_alter(&$blocks, $theme, $code_blocks)

Change block definition before saving to the database.

Parameters

$blocks: A multidimensional array of blocks keyed by the defining module and delta; the values are blocks returned by hook_block_info(). This hook is fired after the blocks are collected from hook_block_info() and the database, right before saving back to the database.

$theme: The theme these blocks belong to.

$code_blocks: The blocks as defined in hook_block_info() before being overwritten by the database data.

See also

hook_block_info()

Related topics

2 functions implement hook_block_info_alter()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

block_test_block_info_alter in modules/block/tests/block_test.module
Implements hook_block_info_alter().
dashboard_block_info_alter in modules/dashboard/dashboard.module
Implements hook_block_info_alter().
1 invocation of hook_block_info_alter()
_block_rehash in modules/block/block.module
Updates the 'block' DB table with the blocks currently exported by modules.

File

modules/block/block.api.php, line 136
Hooks provided by the Block module.

Code

function hook_block_info_alter(&$blocks, $theme, $code_blocks) {
  // Disable the login block.
  $blocks['user']['login']['status'] = 0;
}

Comments

Josh Waihi’s picture

Don't use this hook to unset blocks from other modules. Unlike other alter hooks, removing an index from this array won't help at all.

Instead, it will prevent you from saving blocks to regions and it will clear your database table out for your configured theme.

Potentially this is a core bug, but I guess they never expected blocks to be removed.

tea.time’s picture

You can prevent a block from being saved to any visible region, though:

$blocks['the_module']['the_delta']['region'] = -1;
tea.time’s picture

Actually, there's a Drupal constant for that: BLOCK_REGION_NONE

https://api.drupal.org/api/drupal/modules!block!block.module/constant/BL...

jchristi’s picture

What Josh said is true if you add the code to an existing Drupal site. However, if you use this code in a module that is a dependency at install time (I tested with drush site-install) then unsetting the default blocks from the array appears to work as expected.

djg_tram’s picture

Sure, but there is a simple way to do that:

function hook_block_view_alter(&$data, $block) {
  if ($block->module == 'the_block_you_want_to_suppress') {
    $data['content'] = array();
  }
}
sheldonkreger’s picture

function mymodule_block_info_alter(&$blocks, $theme, $code_blocks) {
  dpm($blocks);
}

This will display all of the array elements you have to work with. Then, it's just a matter of isolating and modifying them.

Note that you must have the devel module installed, and that the dpm() results will only display on the block administration page (this threw me off for awhile, usually dpm() displays output on every page an element is being displayed).

hwasem’s picture

Thanks for the tip about the blocks admin page. I was wondering why it wasn't showing up!

almc’s picture

Would be useful to extend this hook (along with hook_block_info) with defining 'Content types' and 'Roles' for a block. These are included in the block admin UI, but not available to be set up programmatically in unified way in block hooks or API functions.

Chris Gillis’s picture

So you want one module to enable and position a bunch of blocks from other modules for a particular theme? You're looking for something like this:

/**
 * Implements hook_block_info_alter().
 */
function mymodule_block_info_alter(&$blocks, $theme, $code_blocks) {
  if ($theme == 'mytheme') {
    $blocks['othermodule']['blockdelta']['status'] = TRUE;
    $blocks['othermodule']['blockdelta']['region'] = 'myregion';
  }
}