Super-flexible forms in Drupal 5

Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.

It's common practice for theme function writers to give every div a class, so that it can be targetted by CSS. For us, this is especially important in forms, since our clients often ask us to lay out forms in complicated ways.

This was a problem in Drupal 5 (and earlier). Although form elements had ids, so specific elements could be accessed from Javascript and CSS, they are all encased in wrapper divs with class "form-item". This means there's no easy way to lay out a specific form item.

It's been solved in the Drupal 6 version of theme_form_element() by adding unique ids to each form-item container. That's great, but what's better is that the new function works fine in Drupal 5. Just copy it into your template.php file and you've got easy-to-theme forms. Just goes to show how a minor code change can go a long way.

Here's the function:

function theme_form_element($element, $value) {
// This is also used in the installer, pre-database setup.
$t = get_t();

$output = '\n";
$required = !empty($element['#required']) ? '*' : '';

if (!empty($element['#title'])) {
$title = $element['#title'];
if (!empty($element['#id'])) {
$output .= ' '. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."\n";
else {
$output .= ' '. $t('!title: !required', array('!title' => filter_xss_admin($title), '!required' => $required)) ."\n";

$output .= " $value\n";

if (!empty($element['#description'])) {
$output .= ' '. $element['#description'] ."\n";

$output .= "\n";

return $output;