loading...
Cover image for Custom module configuration form for Drupal

Custom module configuration form for Drupal

lukas238 profile image Lucas Dasso ・3 min read

Recently I found my self in the need to add a configuration page to a custom module in Drupal 7.

This module was used to send daily email notification to the users, but settings like the recipient list email address were hardcoded in the code.

To update this list I was forced to update the code repository and make a deploy on production. So this was not ideal.

Oh C'mon!

So I put my self to the task to learn how to improve the custom module by adding its own configuration page.

Finally it only took a couple of hours to read the relevant documentation, implement the code, and perform the relevant tests.

 TL;DR

You can skip directly to the documentation on this links:

Prerequisites

You will need a Drupal instance with a custom module already created for witch you also have access to the source code.

How to

All steps are to be applied on the .module file of your module, except for the step #2 that is to be applied on the .info file of the module.

1. Adding a new menu item

/**
 * Implements hook_menu().
 */
function my_custom_module_menu()
{
    $items = array();

    $items['admin/modules/my_custom_module'] = array(
        'title' => 'My Custom Module configuration',
        'description' => 'Configuration for My Custom Module',
        'page callback' => 'drupal_get_form',
        'page arguments' => array('my_custom_module_admin'),
        'access arguments' => array('administer site configuration'),
        'type' => MENU_NORMAL_ITEM,
    );

    return $items;
}

For this example the custom module name is my_custom_module, so the hook_menu function name must be my_custom_module_menu.

  • We add a new $items to the menu. The key value is the path to the main menu we want for this new page (in this example admin/modules/my_custom_module).
  • The page arguments value points to the function that will be used to populate the form (in this example my_custom_module_admi). We will build this function in the next step.
  • The access arguments value is used to determine who has access to this menu item.

2. Adding a configuration link in the module description

Configuration link

Adding a configuration link on the custom module description page is simple as adding this line to the .info module file:

configure = admin/modules/my_custom_module

This is the same menu path we already used on step #1.

3. Adding items to the form

function my_custom_module_admin($form, &$form_state)
{

    // EMAILS Fieldset
    $form['my_custom_module_settings__emails'] = array(
        '#type' => 'fieldset',
        '#title' => t('Email account settings'),
    );

    // From
    $form['my_custom_module_settings__emails']['my_custom_module_settings__emails__from'] = array(
        '#type' => 'textfield',
        '#title' => t('From address'),
        '#default_value' => variable_get('my_custom_module_settings__emails__from', false),
        '#description' => t('Email address to be used as FROM and Reply-To.'),
        '#required' => true,
    );
    // To
    $form['my_custom_module_settings__emails']['my_custom_module_settings__emails__to'] = array(
        '#type' => 'textarea',
        '#title' => t('To address'),
        '#default_value' => variable_get('my_custom_module_settings__emails__to', false),
        '#description' => t('Recipient email address. You can add multiple email addresses by separating them by a colon (,) character.'),
        '#required' => true,
    );

    return system_settings_form($form);
}

Adding items to the form is simple enough using the Drupal form API documentation.

  • In this example we can find a fieldset and insde two email fields. The first an input text field for the FORM address, and the second a textarea for multiple recipients email addresses.
  • In all the #default_value parameters we make use of the Drupal function variable_get to retrieve the last saved value of the field.
  • The name of the field is the one you specified on the $form array. So, for $form['my_custom_module_settings__emails']['my_custom_module_settings__emails__to'] the variable name will be my_custom_module_settings__emails__to.
  • The last line return system_settings_form($form); will take care to save the form values on submit.

 4. Adding custom validating

function my_custom_module_admin_validate($form, &$form_state)
{

    $from = $form_state['values']['my_custom_module_settings__emails__from'];
    if (!filter_var($from, FILTER_VALIDATE_EMAIL)) {
        form_set_error('my_custom_module_settings__emails__from', t('You must enter a valid FROM email address.'));
    }

    $to = $form_state['values']['my_custom_module_settings__emails__to'];
    echo $to;
    $to = explode(',', $to);
    for ($i = 0; $i < count($to); $i++) {
        $address = trim($to[$i]);
        if (!filter_var($address, FILTER_VALIDATE_EMAIL)) {
            form_set_error('my_custom_module_settings__emails__to', t('You must enter a valid TO email address.'));
            break; //Exit the For/Loop on first error
        }
    }
}

While field parameters like '#required' will take care of basic validation like making a field requiered, some fields may require a more complex check up.

You can add a validation hook with the function name my_custom_module_admin_validate and add your own validations.

  • All form field values will be available inside the $form_state['values'].
  • You can validate multiple fields, and return errors individually by using the Drupal function form_set_error.

Thats all. Happy coding!

Discussion

pic
Editor guide
Collapse
ryancmcconnell profile image
Ryan McConnell

Very nice! I'm familiar with the Drupal 8 Form API, but it's always good to have a Drupal 7 refresher since I'll likely work on Drupal 7 again someday.