Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Apress.Pro.Drupal.7.Development.3rd.Edition.Dec.2010.pdf
Скачиваний:
73
Добавлен:
14.03.2016
Размер:
12.64 Mб
Скачать

CHAPTER 11 THE FORM API

then we would access the data in the following way:

function formexample_nameform_submit($form, $form_state) { $name = $form_state['values']['name']['user_name'];

$color_key = $form_state['values']['color']['favorite_color']; $color = $form_state['values']['color_options'][$color_key]; drupal_set_message(t('%name loves the color %color!',

array('%name' => $name, '%color' => $color)));

}

Tip Setting #tree to TRUE gives you a nested array of fields with their values. When #tree is set to FALSE (the default), you get a flattened representation of fieldnames and values.

Theming Forms

Drupal has built-in functions to take the form data structure that you define and transform, or render, it into HTML. However, often you may need to change the output that Drupal generates, or you may need fine-grained control over the process. Fortunately, Drupal makes this easy.

Using #prefix, #suffix, and #markup

If your theming needs are very simple, you can get by with using the #prefix and #suffix attributes to add HTML before and/or after form elements:

$form['color'] = array( '#prefix' => '<hr />', '#title' => t('Color'), '#type' => 'fieldset',

'#suffix' => '<div class="privacy-warning">' .

t('This information will be displayed publicly!') . '</div>',

);

This code would add a horizontal rule above the Color fieldset and a privacy message below it, as shown in Figure 11-5.

253

CHAPTER 11 THE FORM API

Figure 11-5. The #prefix and #suffix properties add content before and after an element.

You can even declare HTML markup as type #markup in your form (though this is not widely used). Any form element without a #type property defaults to markup.

$form['blinky'] = array(

'#markup' => '<blink>Hello!</blink>' );

Note This method of introducing HTML markup into your forms is generally considered to be as good an idea as using the <blink> tag. It is not as clean as writing a theme function and usually makes it more difficult for designers to work with your site.

Using a Theme Function

The most flexible way to theme forms is to use a theme function specifically for that form or form element. There are two steps involved. First, Drupal needs to be informed of which theme functions our module will be implementing. This is done through hook_theme() (see Chapter 9 for details). Here’s a

254

CHAPTER 11 THE FORM API

quick implementation of hook_theme() for our module, which basically says “Our module provides two theme functions and they can be called with no extra arguments”:

/**

* Implements hook_theme(). */

function formexample_theme() { return array(

'formexample_nameform' => array( 'render element' => 'form', 'template' => 'formexample-nameform',

),

);

}

The template attribute specifies that the template file used to render this form will be named formexample-nameform.tpl.php.

The next step is to use a template preprocess function to gather all of the elements from the form and make those elements available individually so that the themer can control how each element is displayed on the form. The following function assigns each form element to a variable with the key of the variable array being the name of the field—e.g., $variable['formexample_formname']['name'] is the variable containing the text box used to render that field on the form.

/**

*Assign the elements of the form to variables so

*the themer can use those values to control how the

*form elements are displayed, or alternatively

*displaying the whole form as constructed above.

*/

function template_preprocess_formexample_nameform(&$variables) {

$variables['formexample_nameform'] = array(); $hidden = array();

//Provide variables named after form keys so themers can print each element independently.

foreach (element_children($variables['form']) as $key) { $type = $variables['form'][$key]['#type'];

if ($type == 'hidden' || $type == 'token') { $hidden[] = drupal_render($variables['form'][$key]);

}

else {

$variables['formexample_nameform'][$key] = drupal_render($variables['form'][$key]);

}

}

//Hidden form elements have no value to themers. No need for separation.

$variables['formexample_nameform']['hidden'] = implode($hidden);

// Collect all form elements to make it easier to print the whole form. $variables['formexample_nameform_form'] = implode($variables['formexample_nameform']);

}

255

CHAPTER 11 THE FORM API

The next step is to create the .tpl.php file that Drupal will use to render the form. In the sample code here, I am printing each of the form’s fields and have moved the color option above the name field by printing that form field first.

<?php

/**

*@file

*This is the template file for rendering the formexample nameform.

*In this file each element of the form is rendered individually

*instead of the entire form at once, giving me the ultimate control

*over how my forms are laid out. I could also print the whole form

*at once - using the predefined layout in the module by

*printing $variables['formexample_nameform_form'];

*

*/

print '<div id="formexample_nameform">';

print $variables['formexample_nameform']['color']; print $variables['formexample_nameform']['name']; print $variables['formexample_nameform']['submit']; print $variables['formexample_nameform']['hidden']; print '</div>';

// print $formexample_nameform_form;

?>

Telling Drupal Which Theme Function to Use

You can direct Drupal to use a function that does not match the formula “theme_ plus form ID name” by specifying a #theme property for a form:

//Now our form will be themed by the function

//theme_formexample_alternate_nameform().

$form['#theme'] = 'formexample_alternate_nameform';

Or you can tell Drupal to use a special theme function for just one element of a form:

// Theme this fieldset element with theme_formexample_coloredfieldset(). $form['color'] = array(

'#title' => t('Color'), '#type' => 'fieldset',

'#theme' => 'formexample_coloredfieldset'

);

Note that, in both cases, the function you are defining in the #theme property must be known by the theme registry; that is, it must be declared in a hook_theme() implementation somewhere.

256

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]