BTMash

Blob of contradictions

Question and Answer: How do I let another module theme a particular form?

Written

At the Los Angeles Drupal Meetup last night (http://groups.drupal.org/node/135774), John Romine had a particularly interesting question that he later requested I blog about. His question was:

I have a distribution that I am going to be rolling out on campus in which the various departments will have the ability to change themes. However, I have a couple of forms that I would like to see get displayed to the user in a particular way. How to I theme this at the module layer so that the user can use any theme they like and not affect the layout of the particular forms?

Thinking about it, I answered back that you have the ability to set the theme function that would get called for a particular form and this can be done at the form alter layer. So as an example, let's say we wanted to theme the user registration form with the form id user_register_form. Our new module (let's call it my_form_themer) would first need to alter the form and its theme attribute

  1. function my_form_themer_form_alter(&$form, &$form_state, $form_id) {
  2. if ($form_id == 'user_register_form') {
  3. $form['#theme'] = 'my_form_themer_user_register_form';
  4. }
  5. }

This lets the user_register_form to look for a theme function (or template) to use that instead of the standard manner of form generation and rendering.

Now you define hook_theme because the theme registry won't have this theme function registered in there.

  1. function my_form_themer_theme() {
  2. $theme['my_form_themer_user_register_form'] = array(
  3. 'arguments' => array('form' => array()),
  4. 'template' => 'my-form-themer-user-register-form', // This is if you wanted to use a template.
  5. );
  6. return $theme;
  7. }

You will also need to create a tpl file named my-form-themer-user-register-form.tpl.php which would have the various things in there that are necessary to render a form. You can find out more about theming a form at http://drupal.org/node/751826 (you just have to do a lot of print drupal_render($form['element_name']);).

Once you have implemented these parts, you either clear your caches or rebuild the theme registry and voila! Your form rendering is now controlled by a new theme function (or tpl file).