放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

Chapter11 The Form API Drupal

这一章感觉像是讲Drupal的模板引擎,Drupal提供了一个应用程序接口(API),用来生成、验证和处理HTML表单。表单API将表单抽象为一个嵌套数组,里面包含了属性和值。在生成页面时,表单呈现引擎会在适当的时候将数组呈现出来。一个表单模块:

formexample.info

name = Form Example
description = Shows how to build a Drupal form
package = Pro Drupal Development
core = 7.x
files[]=formexample.module

formexample.module

<?php
/**
* @file
* Play with the Form API.
*/
  
/**
 * Implements hook_menu().
 */
function formexample_menu()
{
    $items['formexample'] = array(
            'title' => 'View the sample form',
            'page callback' => 'drupal_get_form',    //当用户访问的路径时,用来显示一个网页的函数。如果省略,父菜单项的回调将被用来代替它。
            'page arguments' => array(               // 传给page callback的参数
                    'formexample_nameform'
            ),
            'access callback' => TRUE,               // 用户是否可以访问,默认为 user_access() ,也可以用常量来代替它
            'type' => MENU_NORMAL_ITEM 
    );
    return $items;
}
/**
 * Define a form.
 * 上面的page callback其实存放的是函数名称,该函数生成一个嵌套数组
 */
function formexample_nameform()
{
    $form['name'] = array(
            '#title' => t('Your Name'),
            '#type' => 'fieldset',
            '#description' => t('What people call you.') 
    );
    $form['name']['user_name'] = array(
            '#title' => t('Your Name'),
            '#type' => 'textfield',
            '#description' => t('Please enter your name.') 
    );
    $form['color'] = array(
            // 直接在这里使用html标记不够干净,应当使用主题函数
//          '#prefix' => '<hr />',
            '#title' => t('Color'),
            '#type' => 'fieldset',
//          '#suffix' => '<div class="privacy-warning">' .
//          t('This information will be displayed publicly!') . '</div>',
            '#description' => t('This fieldset contains the Color field.'),
            '#collapsible' => TRUE,      // 可折叠
            '#collapsed' => FALSE 
    );
    $form['color_options'] = array(
            '#type' => 'value',
            '#value' => array(
                    t('red'),
                    t('green'),
                    t('blue') 
            ) 
    );
    $form['color']['favorite_color'] = array(
            '#title' => t('Favorite Color'),
            '#type' => 'select',
            '#description' => t('Please select your favorite color.'),
            '#options' => $form['color_options']['#value'] 
    );
    $form['submit'] = array(
            '#type' => 'submit',
            '#value' => t('Submit') 
    );
    return $form;
}
/**
 * Validate the form.
 */
function formexample_nameform_validate($form, &$form_state)
{
    if($form_state['values']['user_name'] == 'King Kong')
    {
        // We notify the form API that this field has failed validation.
        // 指明user_name表单域验证失败
        form_set_error('user_name', t('King Kong is not allowed to use this form.'));
    }
}
  
/**
 * Handle post-validation form submission.
 * 提交之后被调用
 */
// function formexample_nameform_submit($form, &$form_state)
// {
//  $color_key = $form_state['values']['favorite_color'];   // 0
//  $color = $form_state['values']['color_options'][$color_key];    //  red1
      
// //   rdump($form_state);
// //   rdump($color_key);
// //   rdump($color, TRUE);
      
//  $name = $form_state['values']['user_name'];
//  drupal_set_message(t('Thanks for filling out the form, %name', array(
//          '%name' => $name 
//  )));
// }
  
function formexample_nameform_submit($form, $form_state)
{
    $name = $form_state['values']['user_name'];
    $color_key = $form_state['values']['favorite_color'];
    $color = $form_state['values']['color_options'][$color_key];
    drupal_set_message(t('%name loves the color %color!', array(
            '%name' => $name,
            '%color' => $color
    )));
}
  
/**
 * Implements hook_theme().
 */
function formexample_theme()
{
    return array(
            'formexample_nameform' => array(
                    'render element' => 'form',
                    'template' => 'formexample-nameform' // 指定将要使用formexample-nameform.tpl.php来渲染
            ) 
    );
}
  
/**
 * 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)
{
    // 直接return的话页面没法渲染
    // return ;
    $variables['formexample_nameform'] = array();
    $hidden = array();
    // Provide variables named after form keys so themers can print each element independently.
    // 提供变量名和键以便主题可以单独打印每个元素
      
    // element_children取出一个数组的子数组
//  krumo($variables);
    foreach(element_children($variables['form']) as $key)
    {
        // 通过element_children知道子数组的名称,比如name color color_options submit form_build_id form_token form_id
//      dpm($key);
        // 把子数组的'#type'属性取出来
        $type = $variables['form'][$key]['#type'];
        if($type == 'hidden' || $type == 'token')
        {
            // 隐藏域和令牌不用管了
            // 令牌,每个表单中都带有它,通过该令牌Drupal能够判定一个表单是一个实际的Drupal表单,而不是一个恶意用户修改后的。
            $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.
    // hidden填入hidden键值
    $variables['formexample_nameform']['hidden'] = implode($hidden);    // implode() 函数把数组元素组合为一个字符串。
    // Collect all form elements to make it easier to print the whole form.
    // 所有的页面元素存到formexample_nameform_form里
    $variables['formexample_nameform_form'] = implode($variables['formexample_nameform']);
}

formexample-nameform.tpl.php

<?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;
?>

最后的效果:

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » Chapter11 The Form API Drupal

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》