4.6.x core.php hook_block($op = 'list', $delta = 0, $edit = array())
4.7.x core.php hook_block($op = 'list', $delta = 0, $edit = array())
5.x core.php hook_block($op = 'list', $delta = 0, $edit = array())
6.x core.php hook_block($op = 'list', $delta = 0, $edit = array())

Declare a block or set of blocks.

Any module can declare a block (or blocks) to be displayed by implementing hook_block(), which also allows you to specify any custom configuration settings, and how to display the block.

In hook_block(), each block your module provides is given a unique identifier referred to as "delta" (the array key in the return value for the 'list' operation). Delta values only need to be unique within your module, and they are used in the following ways:

  • Passed into the other hook_block() operations as an argument to identify the block being configured or viewed.
  • Used to construct the default HTML ID of "block-MODULE-DELTA" applied to each block when it is rendered (which can then be used for CSS styling or JavaScript programming).
  • Used to define a theming template suggestion of block__MODULE__DELTA, for advanced theming possibilities.

The values of delta can be strings or numbers, but because of the uses above it is preferable to use descriptive strings whenever possible, and only use a numeric identifier if you have to (for instance if your module allows users to create several similar blocks that you identify within your module code with numeric IDs).


$op: What kind of information to retrieve about the block or blocks. Possible values:

  • 'list': A list of all blocks defined by the module.
  • 'configure': Configuration form for the block.
  • 'save': Save the configuration options.
  • 'view': Process the block when enabled in a region in order to view its contents.

$delta: Which block to return (not applicable if $op is 'list'). See above for more information about delta values.

$edit: If $op is 'save', the submitted form data from the configuration form.

Return value

  • If $op is 'list': An array of block descriptions. Each block description is an associative array, with the following key-value pairs:

    • 'info': (required) The human-readable name of the block. This is used to identify the block on administration screens, and is not displayed to non-administrative users.
    • 'cache': A bitmask of flags describing how the block should behave with respect to block caching. The following shortcut bitmasks are provided as constants in block.module:

      • BLOCK_CACHE_PER_ROLE (default): The block can change depending on the roles the user viewing the page belongs to.
      • BLOCK_CACHE_PER_USER: The block can change depending on the user viewing the page. This setting can be resource-consuming for sites with large number of users, and should only be used when BLOCK_CACHE_PER_ROLE is not sufficient.
      • BLOCK_CACHE_PER_PAGE: The block can change depending on the page being viewed.
      • BLOCK_CACHE_GLOBAL: The block is the same for every user on every page where it is visible.
      • BLOCK_NO_CACHE: The block should not get cached.
    • 'weight': (optional) Initial value for the ordering weight of this block. Most modules do not provide an initial value, and any value provided can be modified by a user on the block configuration screen.
    • 'status': (optional) Initial value for block enabled status. (1 = enabled, 0 = disabled). Most modules do not provide an initial value, and any value provided can be modified by a user on the block configuration screen.
    • 'region': (optional) Initial value for theme region within which this block is set. Most modules do not provide an initial value, and any value provided can be modified by a user on the block configuration screen. Note: If you set a region that isn't available in the currently enabled theme, the block will be disabled.
    • 'visibility': (optional) Initial value for the visibility flag, which tells how to interpret the 'pages' value. Possible values are:

      • 0: Show on all pages except listed pages. 'pages' lists the paths where the block should not be shown.
      • 1: Show only on listed pages. 'pages' lists the paths where the block should be shown.
      • 2: Use custom PHP code to determine visibility. 'pages' gives the PHP code to use.

      Most modules do not provide an initial value for 'visibility' or 'pages', and any value provided can be modified by a user on the block configuration screen.

    • 'pages': (optional) See 'visibility' above. A string that contains one or more page paths separated by '\n', '\r', or '\r\n' when 'visibility' is set to 0 or 1, or custom PHP code when 'visibility' is set to 2. Paths may use '*' as a wildcard (matching any number of characters); '<front>' designates the site's front page. For 'visibility' setting of 2, the PHP code's return value should be TRUE if the block is to be made visible or FALSE if the block should not be visible.
  • If $op is 'configure': optionally return the configuration form.
  • If $op is 'save': return nothing; save the configuration values.
  • If $op is 'view': return an array which must define a 'subject' element (the localized block title) and a 'content' element (the block body) defining the block indexed by $delta. If the "content" element is empty, no block will be displayed even if "subject" is present.

For a detailed usage example, see block_example.module.

Related topics

27 functions implement hook_block()

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

aggregator_block in modules/aggregator/aggregator.module
Implementation of hook_block().
block_block in modules/block/block.module
Implementation of hook_block().
blog_block in modules/blog/blog.module
Implementation of hook_block().
book_block in modules/book/book.module
Implementation of hook_block().
comment_block in modules/comment/comment.module
Implementation of hook_block().

... See full list


developer/hooks/core.php, line 206
These are the hooks that are invoked by the Drupal core.


function hook_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    $blocks[0] = array(
      'info' => t('Mymodule block #1 shows ...'),
      'weight' => 0,
      'status' => 1,
      'region' => 'left',

    // BLOCK_CACHE_PER_ROLE will be assumed for block 0.
    $blocks[1] = array(
      'info' => t('Mymodule block #2 describes ...'),
    return $blocks;
  else {
    if ($op == 'configure' && $delta == 0) {
      $form['items'] = array(
        '#type' => 'select',
        '#title' => t('Number of items'),
        '#default_value' => variable_get('mymodule_block_items', 0),
        '#options' => array(
      return $form;
    else {
      if ($op == 'save' && $delta == 0) {
        variable_set('mymodule_block_items', $edit['items']);
      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' => mymodule_display_block_1(),
            case 1:

              // Your module will need to define this function to render the block.
              $block = array(
                'subject' => t('Title of block #2'),
                'content' => mymodule_display_block_2(),
          return $block;


minghui.yu’s picture

To put a block in a region when $op = 'list' , you need to give a string index to the $blocks array.

For example:

    switch ($op) {
      case 'list':
        $blocks['some_string'] = array(
          'info' => 'I am in Footer',
          'status' => 1,
          'region' => 'footer',

        $blocks[1] = array(
          'info' => 'I am supposed in Footer but I do not',
          'status' => 1,
          'region' => 'footer',

The first block is listed in footer region but the second one is not.

wdmartin’s picture

Note that you cannot implement hook_block() in the template.php for a theme. It has to be placed in a module. Putting an implementation of hook_block() into your template.php will cause all the blocks on the site to stop working until you remove the function and clear Drupal's cache.

trungonly’s picture

I have a module and a theme with same name "xyz". When I implement hook_block for module "xyz", yes like wdmartin wrote, all other blocks disappeared! That does not happen with other themes with different name. Even placed the hook in module, because of the same name, Drupal may treat it as in hook of the theme.

Conclusion, to prevent this issue, you should not name your module and your theme with the same name.

kiamlaluno’s picture

Drupal 7 doesn't use anymore hook_block(), but it uses a set of new hooks; see Converting 6.x modules to 7.x for more details.

blackdog’s picture

If you use strings as delta, make sure your strings are shorter than 32 characters, otherwise they get cut off, and your 'view' block will not have the same value.

kevee’s picture

On the list of possible return values, the unordered list is not ordered correctly. The three last $op values should be first-level list items, not sub-items of if $op = list.

snufkin’s picture

Delta is later used as part of the block class, so if you are implementing a custom set of blocks you might want to use a string instead of an integer.

EvanDonovan’s picture

To print the content of a block in a node (with the PHP input format) or tpl.php (note that you may want to use a preprocess function), you can use the following:

$block = module_invoke($module, 'block', 'view', $delta);
print $block['content'];

Set $module to the name of the module providing the block, and $delta to its delta. Usually the block id includes this information.

georgir’s picture

instead of print $block['content'] you should use:
print theme('block', $block);
to also get the title, borders or whatever other decorations are defined by your theme

EvanDonovan’s picture

Thanks - I didn't think about this. I think there are some circumstances - i.e., inside a node or panel, etc., where you don't want the full block, but just the content it provides. But yes, if you're working in the theme layer, in a page.tpl.php or something, this might be a better option.

kenorb’s picture

Sivaji’s picture

    $blocks[0] = array(
      'info' => t('Mymodule block #1 shows ...'), 
      'weight' => 0, 
      'status' => 1, 
      'region' => 'left',

When you implement hook_block() DON'T USE region which is not defined in your theme. Failing to do so prevents block from listing in admin/build/block page. I had to rename my module to restore it to default state. Better just define 'info' and do the rest from admin/build/block page. This is yet another DrupalWTF.

agungsuyono’s picture

That problem occurs when you set 'status' => 1 and the 'region' is not defined. To fix this problem, simply set 'status' => FALSE and delete this block's delta in {blocks} table in the database ('DELETE FROM {blocks} WHERE delta = ' . $delta). After that, open admin/build/block and your block will be listed there.

danmatthews’s picture

For the love of god, please read the example provided here http://drupal.org/node/1050754, to save yourself days of hair-pulling frustration.

andreigg’s picture

Set the keys in the $blocks array as something unique, otherwise the block will not show in the blocks admin listing:

$blocks[0] = array(...); // this doesn't work
$blocks['unique-string'] = array(); // this works!
kingandy’s picture

In Drupal 7 this hook has been replaced with a family of functions. The list, configure, save and view operations are carried out by hook_block_info(), hook_block_configure(), hook_block_save() and hook_block_view(), respectively.