Friday, April 18, 2008

Creating a module admin settings page in Drupal 6

I am new to Drupal, newer to coding Drupal and I was attempting to code a new module. Recipie for beginners block :) Anyways, among other features the module was supposed to have a settings page where certain settings, pertaining to that module, could be configured by the site administrator.

The help files at Drupal were proving to be fairly non-trivial and unwieldy, so I started looking outside the drupal ecosystem for some valuable tips. And very conveniently I stumbled across this tutorial from IBM. However, it has been written for Drupal 4.6 indicating that I could expect to do a fair bit of porting.

The very first "hook" that the example extends is hook_settings().

"The settings hook provides a way to add attributes to the module that can be controlled by the administrator and can be used when displaying this module."
Just what I was looking for! But hang on a sec, it doesn't even exist in Drupal 6. Anyways, lets us see how those folks have done it

Listing 1: hook_settings as extended by IBM's tutorial
function announcement_settings() {
$form = array();
$form['announcement_block_max_list_count'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of block announcements'),
'#default_value' => variable_get('announcement_block_max_list_count', 3),
'#description' => t('The maximum number of items listed in the announcement block'),
'#required' => FALSE,
'#weight' => 0
);
return $form;
}
Fairly easy, define and array and return the admin settings in that array object and thats it, all done. Simple, but as far as I am concerned - useless! As mentioned earlier, drupal 6 doesn't even recoginze this hook, so I had to ask my self, how can I do this in drupal 6? But, before that one may ask the question, why was this function deprecated? The answer may lie in it being interpreted as being too restrictive - i.e. only form objects are allowed, what if I wanted some elaborate content at the admin settings page. Of course, the necessity of such elaborate content will always be in doubt. Nevertheless, this the lemon we've been handed... anyways, coming back to that settings page. How do we get a settings page in Drupal 6.x?

The answer lies in extending hook_menu(), as shown below -
function announcement_menu() {
$items = array();
$items['admin/settings/announcement'] = array(
'title' => t('Maximum number of block announcements'),
'description' => t('The maximum number of items listed in the announcement block'),
'page callback' => 'drupal_get_form',
'page arguments' => array('announcement_settings_form'),
'access callback' => 'user_access',
'access arguments' => array('administer announcement'),
'type' => MENU_NORMAL_ITEM
);
return $items;
}

function announcement_settings_form($form_state) {
$form = array();
$form['uploaded_block_max_list_count'] = array(
'#type' => 'textfield',
'#title' => t('Maximum number of block announcements'),
'#default_value' => variable_get('announcement_block_max_list_count', 3),
'#description' => t('The maximum number of items listed in the announcement block'),
'#required' => FALSE,
'#weight' => 0
);
return system_settings_form($form);
}
In drupal 4.6 the _settings() hook would mimic the url http:///admin/settings/. When coding with drupal 6.x, to maintain backward compatibility, a new menu item is added such that the menu system will look for a menu item at the path "admin/settings/", in our case it is "admin/settings/announcement". This is done by defining an item element as
$items['admin/settings/announcement'] = array(...)
The page callback is used to return the page which needs to be displayed for the url defined by the menu item. In our case we use the "drupal_get_form" as the callback. The "drupal_get_form" function is described as
"Retrieves a form from a constructor function, or from the cache if the form was built in a previous page-load. The form is then passesed on for processing, after and rendered for display if necessary.

$form_id The unique string identifying the desired form. If a function with that name exists, it is called to build the form array..."
Thus to reproduce the same effect as 4.6, we pass the "announcement_settings_form" function, which is very similar to the 4.6 "announcement_settings" hook implementation, as an argument to the page callback.

Access callback and access parameters are used to define the permission levels for this particular url.

And that is how it is all done!

No comments: