In a project I am working on we are trying to combine the power of a wonderful HTML compliant theme with the flexibility of drupal theme functions.

A requested output was that in specific forms the form elements should look like this : http://drupal.pastebin.com/s16UG4Kn

Whenever you’d like to theme a form you could use the theming function theme_form_element(). This function works wonderful until the moment that you need to switch the theming of all the elements in a specific form. To make it more complicated, the forms are for example the user_register form which is heavily modified.

```
function mytheme_form_element($element, $value) {
```

But apparently you can not switch themes within this function depending on the form_id. You could however add a #theme attribute to all the form elements or a custom variable, both solutions suffice. It’s a matter of handing out responsibilities to the right functions.

After doing numerous tryouts we found the following solution gaining the most satisfaction.

```
/**
* Implementation of hook_form_alter().
*/
function mymodule_custom_form_alter(&$form, &$form_state, $form_id){
  foreach($form as $form_element_name => $form_item ) {
      //add the form_id to every element
      if(is_array($form_item) && isset($form_item['#type'])) {
        $form[$form_element_name]['#mymodule_form_id'] = $form_id;
      }
      //we use AHAH helper so whenever an element is rebuild we also need the form_id in this element
      if(is_array($form_item) && isset($form_item['#type']) && isset($form_item['#ahah'])) {
        $form[$form_element_name]['#ahah']['mymodule_form_id'] = $form_id;
      }
  }
}
```

This code might seem a bit abstract but does the following.

  • Adds form_id to every element as a custom attribute
  • Whenever we use a ahah form element the custom attribute is not added to the rebuilded item. (if someone knows why?) so we also need to add it to the AHAH property as a seperate variable.

Then we can use the following theming function to solve our problem :

```
/**
 * Return a themed form element.
 *
 * @param element
 *   An associative array containing the properties of the element.
 *   Properties used: title, description, id, required
 * @param $value
 *   The form element's data.
 * @return
 *   A string representing the form element.
 *
 * @ingroup themeable
 */
function mytheme_form_element($element, $value) {
  if (isset($element['#mymodule_form_id'])) {
      $mytheme_form_id = $element['#mymodule_form_id'];
  } else if(isset($element['#ahah']['mymodule_form_id'])) {
      $mytheme_form_id = $element['#ahah']['mymodule_form_id'];
  }



  switch ($mytheme_form_id) {
  case 'search_form':
    return mytheme_form_element_search($element, $value);
  case 'user_register':    
    return mytheme_form_element_user($element, $value);
  default:
    return mytheme_form_element_default($element, $value);
  } // switch

}
```

I hope we can at least help 1 other person by posting these instructions. Thankfully Drupal is powerful enough to allow us to override these functions. Drupal and Nick, we’re still good friends ;-)

If you would know a better way (without adding theme function to every element?) please leave a comment! I am still doubting if this is the way to go but I had to get this out there because it is mostly not so easy to find the more optimal solution.