How Form Markup is Generated
Forms are generated by modules. The simple function shown in Listing 16–24 is all that is required to generate form markup. It looks really easy, doesn’t it? It is. Of course, there is more to the process to make it functional, such as validating the form and saving the submitted values, but the rest is not your concern in the theme layer. What’s important to you is the structure of a form and how it’s transformed from the
$form array to actual markup.
In Listing 16–24, you define a very simple form with two elements: a textfield for the e-mail address and a submit button. When rendered, the result looks like those in Figure 16–5. The resulting markup is shown in Listing 16–25.
Form API Elements and Default Properties
exampleform_unsubscribe() form, you’ve defined two form elements: the e-mail address and the submit element. The e-mail element’s
#type property is textfield, which provides a single line text input. The submit element’s
#type is submit, which is the Form API equivalent of
<input type="submit" />.
If you look closely at the generated markup in Listing 16–25, you’ll see that you only set two properties in each element, but your markup ended up with some additional attributes. This is because Drupal assigns a default set of properties to each element. In this case, you are using form, textfield, and submit elements, which are defined in
system_element_info(), as shown in Listing 16–26. When the form is processed, Drupal merges the properties defined in the form with the default properties.
Rendering of Form Elements
The element properties contain critical information required to render them. Of these properties, two are very important in the theme layer:
#theme_wrappers. When it’s time to render the form, these properties tell Drupal which theme functions to use. There’s also the option to use the
#pre_render property to define a function(s) that should run prior to rendering.
- Specifies the theme function to use when rendering the element.
- Specifies a theme function or functions that should be used to wrap the rendered children of the element.
To illustrate this process, let’s use the
$form['email'] field from the previous form and walk through the process:
theme('textfield', array('element' => $form['email']))is called. This results in the following markup:
- <input type="text" id="edit-email" name="email" value="" size="60" maxlength="128" class="form-text required" />
theme('form_element', array('element' => $form['email']))is called. This results in the following markup:
- <div class="form-item form-type-textfield form-item-email">
- <label for="edit-email">E-mail address <span class="form-required" title="This field is required.">*</span> </label>
- <!-- RESULT OF THE RENDERED TEXTFIELD -->
Finally, after all of the form elements are rendered, the form itself is run through
theme_form(), which is specified as the
#theme_wrappersin the form element. The
theme_form()function takes care of generating the rest of the form markup, including the hidden elements