Drupal 7 Blocks: What's Changed Under the Covers
Blocks in Drupal 6 (and 5) always felt a little less loved than other portions of Drupal. While the node and theming APIs offered straightforward and often elegant methods to modify behaviour without modifying other peoples' code, blocks weren't so fortunate. Lacking API support, working with blocks often meant writing ugly code. Last week helping with the Drupal Block API documentation I discovered this has changed in Drupal 7. I thought I'd share what I learned.
The information I'll discuss is a summary of the block information from:
- Converting 6.x modules to 7.x (http://drupal.org/node/224333)
- Converting 6.x modules to 7.x - Categorical (http://drupal.org/node/394070)
- Block API Documentation: block.api.php
- Examples Module: block_examples.module (From: Examples for Developers project)
hook_block() has been split up
The Drupal 7 Block API's most noticeable change is the splitting of hook_block():
- hook_block_info() replaces hook_block($op = 'list)
- hook_block_view() replaces hook_block($op = 'view')
- hook_block_configure() replaces hook_block($op = 'configure')
- hook_block_save() replaces hook_block($op = 'save')
Hopefully gone are those sometimes awkward select statements.
Hook Alters
The Drupal 7 Block API now has alter hooks! These new hook provide a clean way to modify other blocks in the system:
- hook_block_info_alter()
This hook allows you to change a block definition before it's saved to the database. - hook_block_list_alter()
This hook allows you to add, remove or modify block definitions in the block list. This happen before the blocks are rendered, so you can even override the contents of the block. This hook can replace the use of db_rewrite_sql() or hook_query_alter() for altering the blocks list. - hook_block_view_alter()
This hook allows you to modify the contents of any block returned by hook_block_view(). - hook_block_view_MODULE_DELTA_alter
A convenience hook of sorts, this hook allows you modify the contents of a specific block rather than implementing hook_block_view_alter() and testing every call for the block of interest.
$delta module ID is text
The unique block ID within a module is known as the block "delta" and it's now a string instead of an integer. Blocks can now be given meaningful names. For example, instead of being identified as 1, a block might be identified as "index" or "groups". CSS classes and theming suggestions use this name as well, improving readability.
If you are a module maintainer be sure to read the notes on updating your block configuration from Drupal 6 to Drupal 7. There's a helper function provided.
Renderable Arrays as Output
Blocks should now return their output as renderable arrays. For example:
$block['content'] = array('#markup' => t('This is my string of text to display'));
This is part of an overall Drupal 7 change and not specific to blocks. Strings will continue to work, but a renderable array is strongly recommended.
Database Table Changes
The block tables have been renamed:
- 'blocks' renamed to 'block'
- 'blocks_roles' renamed to 'block_role'
- 'boxes' renamed to 'block_custom'
Block Module Optional
Although enabled by default, the block module is not required and can be disabled. If you write code that relies on the block module be sure to declare it as a dependency in your module .info file or wrap the code in a statement that verifies the block module is enabled. For example: if (module_exists('block')) {...}
Permission String Change
The permission string "use PHP for settings" is replaced by "use PHP for block visibility".
Cache Constants Renamed
The BLOCK_CACHE_ prefix for cache constants is now DRUPAL_CACHE_.
See http://api.drupal.org/api/function/hook_block_info/7 for the list of constants.
Thanks
A big thank you to everyone who updated the code and documentation. Drupal 7 blocks have come a long way thanks to your effort!
Comments
Mistake in the example
$delta
still mistake in renderable arrays!
=> is shown as =>
Thanks
Reason for string $delta
Glad you caught that deltas could be strings in Drupal 6, but Drupal core itself used integers. Strings are highly recommended because they make Drupal entities easier to export and because the delta will be used in the block ID in HTML. #block-user-login is so much nicer in our CSS than #block-user-0 (yep, that's the login block in Drupal 6).
Thanks for the explanation
Thanks for the explanation Benjamin! I'll update the paragraph when I get a chance.
Credit goes to Mikeytown2 for catching the Drupal 6 strings error.