Setting up a Custom Admin Page using system_settings_form() in Drupal 7


Have you ever needed an admin page to store a few simple values for site configuration?  One way to meet that need would be to create the three drupal form functions: the form function itself, the _validate function , and the _submit function.  This seems like a little overkill, however, and if you’re doing something really simple (like saving the values via variable_set, for example), then it seems even more like overkill as you basically have to duplicate a lot of the code from the form function in the submit function.

Surely there’s a better way.

There is!  With Drupal’s form-building API, you can actually do away with both the _validate function and the _submit function.  It’s called system_settings_form(), and it’s a function tied to Drupal’s System module.  At its most basic level, this allows you to create a single function for your form and let Drupal work all the magic.  Here’s an example:

function mymodule_admin_page_form() {
                $form = array();

                $form['mymodule_path'] = array(
                                '#type' => 'textfield',
                                '#title' => t("URL"),
                                '#weight' => 1,
                );

                return system_settings_form($form);
}

So what happens here?  Well, let’s see.  We’ve created a $form array and have filled it out with a single field, ‘mymodule_path’.  Assuming you’re familiar with Drupal 7’s form API, you’ll see that we’ve set up a text field with the title ‘URL’.  And...  That’s really all we’ve done.  We’ve then returned the value of a function call, rather than the $form element (as you’d expect).  This is very important!  The return value is what drives this process.  Drupal will magically display a ‘Submit’ button, and will handle the form submission for you, as well!

But where does the value of the ‘mymodule_path’ field go?  It gets stored via Drupal’s variable_set() function.  It sets/creates a variable named after the field it’s saving – so in this case it would be something like variable_set(‘mymodule_path’, $value);  You can find its value at any time using variable_get().  In fact, since we’re displaying a form to set this value, it makes a lot of sense to pull its current value (assuming it has one) as a default value for our form item, doesn’t it?

function mymodule_admin_page_form() {
                $form = array();

                $form['mymodule_path'] = array(
                                '#type' => 'textfield',
                                '#title' => t("URL"),
                                '#default_value' => variable_get('mymodule_path', 'sites/default/files/header-welcome.jpg'),
                                '#weight' => 1,
                );

                return system_settings_form($form);
}

So what have we done here?  Simple!  We’ve added a default value to the form element mymodule_path, which relates back to a variable_get() call.  If there’s no value stored in the Drupal variable ‘mymodule_path’, we get the value 'sites/default/files/header-welcome.jpg'

...And that’s all you have to do.  You can create a menu entry for this that looks something like the following:

function mymodule_menu() {
                $items = array();

                $items['admin/mymodule/path'] = array(
                                'title' => 'Path Config',
                                'description' => 'Configure path for mymodule purposes',
                                'page callback' => 'drupal_get_form',
                                'page arguments' => array('mymodule_admin_page_form'),
                                'access arguments' => array('access administration pages'),
                                'type' => MENU_NORMAL_ITEM,
                );
                return $items;

}

Now when you go to http://www.yoursite.com/admin/mymodule/path, you will see a fully-functioning form with a text field titled ‘URL’ and a value of ‘sites/default/files/header-welcome.jpg’ and a ‘submit’ button!

Tags: