3 min read

Creating a Drupal block with configuration form

Drupal makes it easy to create custom blocks. Thanks to its flexible system, we can create new blocks with any content using modules. This article explains how to create a custom block and add a configuration form, which is often required for block settings from the site admin interface.

First, let’s create the block and fill it with content using hooks hook_block_info and hook_block_view:

/**
 * Implements hook_block_info().
 */
function example_block_block_info() {
  $blocks['random_numbers'] = array(
    'info' => t('Random numbers'),
  );

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function example_block_block_view($delta) {
  $block = array();

  switch ($delta) {
    case 'random_numbers':
      $block['subject'] = t('Random numbers');
      $block['content'] = example_block_random_numbers();
      break;
  }

  return $block;
}

To add a custom form to the block configuration page, use hook_block_configure. Within this hook, you can add any form and use the results when rendering the block’s content:

/**
 * Implements hook_block_configure().
 */
function example_block_block_configure($delta = '') {
  $form = array();

  switch ($delta) {
    case 'random_numbers':
      $form['random_numbers_count'] = array(
        '#type' => 'textfield',
        '#title' => t('Count numbers'),
        '#default_value' => variable_get('random_numbers_count', 5),
        '#element_validate' => array('element_validate_number'),
        '#required' => TRUE,
      );
      break;
  }

  return $form;
}

/**
 * Implements hook_block_save().
 */
function example_block_block_save($delta = '', $edit = array()) {
  switch ($delta) {
    case 'random_numbers':
      variable_set('random_numbers_count', $edit['random_numbers_count']);
      break;
  }
}

In the code above, we create a form with a single text element and save its value to a variable. Note the element_validate attribute used for form validation. In this example, a standard numeric validation function is used, but you can write your own function and specify it as the element validator. You can also specify a validation function for the entire form.

Full module source code example_block.module:

<?php
/**
 * @file
 * Example block
 */

/**
 * Implements hook_block_info().
 */
function example_block_block_info() {
  $blocks['random_numbers'] = array(
    'info' => t('Random numbers'),
  );

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function example_block_block_view($delta) {
  $block = array();

  switch ($delta) {
    case 'random_numbers':
      $block['subject'] = t('Random numbers');
      $block['content'] = example_block_random_numbers();
      break;
  }

  return $block;
}

/**
 * Implements hook_block_configure().
 */
function example_block_block_configure($delta = '') {
  $form = array();

  switch ($delta) {
    case 'random_numbers':
      $form['random_numbers_count'] = array(
        '#type' => 'textfield',
        '#title' => t('Count numbers'),
        '#default_value' => variable_get('random_numbers_count', 5),
        '#element_validate' => array('element_validate_number'),
        '#required' => TRUE,
      );
      break;
  }

  return $form;
}

/**
 * Implements hook_block_save().
 */
function example_block_block_save($delta = '', $edit = array()) {
  switch ($delta) {
    case 'random_numbers':
      variable_set('random_numbers_count', $edit['random_numbers_count']);
      break;
  }
}

/**
 * Generate random numbers.
 */
function example_block_random_numbers() {
  $numbers = array();
  $count = variable_get('random_numbers_count', 5);
  for ($i = 0; $i < $count; $i++) {
    $numbers[] = rand(0, 1000);
  }
  return theme('item_list', array('items' => $numbers));
}