Optimise configuration forms

Optimising configuration forms in Drupal 7

When you're creating modules in Drupal 7, most likely you'll end up creating some kind of configuration forms for your module. In Drupal 7 the easiest way to do this is through variables.

Since this is the easiest way, most people use them but don't overuse them since they're loading on every page load, which is why we don't want to have many variables in the variables table.

How to create configuration forms in Drupal 7

There is a bad way and a better way to create configuration forms in Drupal 7, and I'll use both ways to show the difference. First let's start with the bad way, which is to simply create a form with each item having its own variable. 

function custom_table_form_admin_settings() {
  $users = [
    'anonymous',
    'authenticated'
  ];
  foreach($users as $user) {
    $form['comparison_table_'.$user.'_q1'] = array(
      '#type' => 'textfield',
      '#title' => t('First quote '. ucfirst($user)),
      '#description' => t('First quote.'),
      '#default_value' => variable_get('comparison_table_'.$user.'_q1', ''),
      '#required' => FALSE,
    );
    $form['comparison_table_anonymous_'.$user.'_q2'] = array(
      '#type' => 'textfield',
      '#title' => t('Second quote ' . ucfirst($user)),
      '#description' => t('Second quote.'),
      '#default_value' => variable_get('comparison_table_'.$user.'_q2', ''),
    );
  }
  return system_settings_form($form);
}

The form will look like this:

Optimising configuration forms fig. 1

As you can see each item has it own variable. In the process you could also do something like iterate through some of your system items and generate configuration for them. That would probably result in about 100+ variables or as many config items as you want the configuration for in the variable table. Of course, this is a bad practice and it will result in slow page load since variables are loaded on every page load. The form looks ugly, and you'll have a bunch of variables to delete afterwards on uninstall. Also if your variable is related to some items that gets deleted you end up having to delete it on appropriate hook into your process.

Now there is a better way to do this. So If you need to have configuration create a fieldsets and use #tree property. For example:

function custom_table_form_admin_settings() {
  $users = [
    'anonymous',
    'authenticated'
  ];
  $comparison_table_settings = variable_get('comparison_table_settings','');
  $form['comparison_table_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Comparison table settings'),
    '#description' => t('Comparison table settings for users'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#tree' => TRUE,
  );
  foreach($users as $user){
    $form['comparison_table_settings'][$user] = array(
      '#type' => 'fieldset',
      '#title' => t(ucfirst($user) .' user'),
      '#description' => t('Comparison table settings for anonymous user'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
    );
    $form['comparison_table_settings'][$user]['q1'] = array(
      '#type' => 'textfield',
      '#title' => t('First quote'),
      '#description' => t('First quote.'),
      '#default_value' => isset($comparison_table_settings[$user]['q1']) ? $comparison_table_settings[$user]['q1'] : '',
      '#required' => FALSE,
    );
    $form['comparison_table_settings'][$user]['q2'] = array(
      '#type' => 'textfield',
      '#title' => t('Second quote'),
      '#description' => t('Second quote.'),
      '#default_value' => isset($comparison_table_settings[$user]['q2']) ? $comparison_table_settings[$user]['q2'] : '',
    );
  }
  return system_settings_form($form);
}

This will result in only ONE variable which will be only one row in variable table and that is comparison_table_settings which will be updated when you save config form. If we take a look at dump from variable we see how the unserialised variable looks like. So only one unserialize() function will be called. If you load your items from something in your system you don't have to hook anywhere to delete variables because you only have one.

Optimising configuration forms fig. 2

Our new form looks better, it's grouped by fieldsets and we only have one variable for all configuration items.

So once we want to uninstall the module we can perform only one variable_del in hook_uninstall and it will delete our complete configuration.

Keep this in mind when you're working on Drupal 7 modules.

Share this post