Things I learned about Drupal - Apr 28, 2011


First, let me yammer

Lately I've been writing some patch code for the Drupal 7 version of Organic Groups and Organic Groups Create Permissions. Both modules are cornerstones on which I plan to build deninet 7. This isn't the first time I've written Drupal code, but it is the first time I've done so for a patch to contrib modules. 

Historically I've had bad luck writing code for Drupal. Often I start a module only to throw it away a short time later, unfinished. Usually I run into a complicated issue, or my responsibilities eat me alive. Patch code isn't the same as a complete module, although I think each line of code is more hard fought than writing something new from scratch. 

The last two days I've learned a few things about Drupal code. Last night I asked myself, "what did I learn today?" This afternoon it occured to me that I should -- if only for my own reference -- what I did, in fact learn.

System Settings forms and Variable Names

The maintainer of the Drupal 7 version of Oranic Groups suggested that I write a patch to include a feature that would assign a default group role to the creator of the group. After digging around, I found a good place to insert the code would be under Admin > Groups > Settings.

When I found the function that generated the page, it ended in a Drupal API call system_settings_form(). Here's the function as of this afternoon:

function og_ui_user_admin_settings($form_state) {
  $form = array();

  $form['og_group_manager_full_access'] = array(
    '#type' => 'checkbox',
    '#title' => t('Group manager full permissions'),
    '#description' => t('When enabled the group manager will have all the permissions in the group.'),
    '#default_value' => variable_get('og_group_manager_full_access', TRUE),

  $roles = og_roles();
  $roles['_none'] = 'No default role';

  $form['og_manager_default_role'] = array(
	'#type' => 'select',
	'#title' => t('Default role for group managers'),
	'#default_value' => variable_get('og_manager_default_role', '_none'),
	'#options' => $roles,
	'#description' => t('The role to assign to group managers when the group is created. Most sites should select a role with the Edit Group and Administer Group permissions.'),
  return system_settings_form($form);

Notice that there are two form fields -- og_group_manager_full_access, and the code I added for og_manager_default_role. Since Drupal 4.7, forms in Drupal have been written in the Form API, rather than HTML. At the end of the function is a call to system_settings_form().

Now, I remember from the few times I've tried to write Drupal code that a function that creates a form -- og_ui_user_admin_settings() in this case -- is usually paired with a function with the same name ending in _submit(). But looking around, I found no such function! How did Drupal know how to save the data entered in the form?

The key is the form field names. Notice that with in the array body of each form statement there's a call to variable_get(). The first parameter of variable_get() is the name of the variable to get, the second parameter is the default if the variable does not exist. See anything interesting? The names of the variables passed to variable_get() are the same as the form field name! In this case, og_group_manager_full_access and og_manager_default_role. 

It turns out that system_settings_form() expects that form field names correspond to the variable names used to store the value in the Drupal database. So, when the user submits the form, Drupal knows to save the values entered as variables with the same name as the form element. No need for a *_submit() function!

You can override this behavior if necessary with your own custom submit function, but it's not necessary in many cases.