Form API Drupal 7 —— 在 Drupal 中创建表单
在前几节课程中,我们已经学习了钩子 hook_block_info()、hook_block_view()、hook_menu() 和 hook_permission(),因此我们现在已经能够通过编程方式创建任意数量的页面和区块。而在本节中,我们将学习 Drupal 7 的 Form API,用于创建表单。我们将创建一个用于模块管理的表单,并尽量使用我们已经掌握的钩子来巩固知识。
首先,我们输出 3 个区块,这对你来说应该已经不难了:
function sitemade_block_info(){ $blocks = array(); // 初始化一个空数组 $blocks[1]['info'] = '用户列表'; // 后台显示的区块标题 $blocks[2]['info'] = '节点列表'; $blocks[3]['info'] = '术语列表'; return $blocks; // 返回区块列表 } function sitemade_block_view($delta = ''){ $block = array(); // 初始化区块数组 switch ($delta){ case 1: $block['subject'] = '用户'; // 区块标题 $block['content'] = ''; $query = db_select('users', 'u') // 查询用户表 ->fields('u', array('uid', 'name')) ->orderBy('u.uid', 'DESC') // 按 UID 倒序 ->range(0, 5) // 仅取前 5 个用户 ->execute(); $users = $query->fetchAll(PDO::FETCH_ASSOC); foreach($users as $user){ $block['content'] .=''; } break; case 2: $block['subject'] = '节点'; $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, 10) ->execute(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach($nodes as $node){ $block['content'] .=''; } break; case 3: $block['subject'] = '术语'; $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, 10) ->execute(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach($terms as $term){ $block['content'] .=''; } break; } return $block; }
清除缓存以便让新建区块出现在后台。然后将这些区块输出到左侧边栏:
接下来我们创建一个后台页面,用于管理这三个区块:
function sitemade_permission(){ return array( 'admin content blocks' => array( 'title' => t('管理内容区块'), 'description' => t('节点、用户、术语'), ), ); } function sitemade_menu(){ $items = array(); $items['admin/config/content/content_blocks'] = array( 'title' => '用户、节点、术语区块', 'description' => '区块管理', 'page callback' => '_sitemade_content_blocks', 'access arguments' => array('admin content blocks'), ); return $items; } function _sitemade_content_blocks(){ $content = 'Lorem ipsum!'; return $content; }
创建的页面应该在 admin/config/content/content_blocks 地址出现:
接着,我们为管理员添加查看该页面的权限(这就是我们实现 hook_permission() 的原因)。
接下来我们修改代码,创建一个管理表单。我们将在表单中配置区块标题以及显示的实体数量(节点、用户、术语)。
首先修改 hook_menu 的 'page callback' 属性:
function sitemade_menu(){ $items = array(); $items['admin/config/content/content_blocks'] = array( 'title' => '用户、节点、术语区块', 'description' => '区块管理', 'page callback' => 'drupal_get_form', 'page arguments' => array('_sitemade_content_blocks'), 'access arguments' => array('admin content blocks'), ); return $items; }
drupal_get_form($form_id)
drupal_get_form() 是 drupal_build_form() 的封装,用于在不需要 $form_state 的情况下调用。
参数说明
- $form_id:表单的唯一标识符。
- 任何其他参数都会传递给对应的表单构建函数。
返回值
返回表单数组。
因此我们需要重写函数 _sitemade_content_blocks()
以返回表单数组:
function _sitemade_content_blocks(){ $form = array(); $form['nodes-title'] = array( '#type' => 'textfield', '#title' => t('节点区块标题'), '#default_value' => variable_get('node_block', ''), '#size' => 60, '#maxlength' => 64, '#description' => t('节点区块的标题'), ); $form['node-selected'] = array( '#type' => 'select', '#title' => t('节点数量'), '#options' => array(1 => t('1'), 2 => t('2'), 3 => t('3'), 4 => t('4'), 5 => t('5'), 6 => t('6'), 7 => t('7'), 8 => t('8'), 9 => t('9'), 10 => t('10')), '#default_value' => variable_get('node_block_range', 5), '#description' => t('显示在区块中的节点数量'), ); ... $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('保存'), ); return $form; }
最终我们得到一个如下的后台表单:
表单已经渲染,现在我们添加提交处理函数。使用钩子 hook_formID_validate() 和 hook_formID_submit() 分别用于验证和保存数据。
表单生成与提交
Drupal 使用 drupal_get_form() 来生成和处理表单,也可以使用 drupal_form_submit() 在没有用户交互的情况下提交表单。
下面是一个示例:
$form = drupal_get_form('my_module_example_form'); ... function my_module_example_form($form, &$form_state) { $form['submit'] = array( '#type' => 'submit', '#value' => t('提交'), ); return $form; } function my_module_example_form_submit($form, &$form_state) { // 表单处理逻辑 }
现在我们为表单添加提交处理逻辑,使其保存表单数据到 Drupal 变量:
function sitemade_content_blocks_submit($form, &$form_values){ variable_set('node_block', $form_values['values']['nodes-title']); variable_set('user_block', $form_values['values']['users-title']); variable_set('term_block', $form_values['values']['terms-title']); variable_set('node_block_range', $form_values['values']['node-selected']); variable_set('user_block_range', $form_values['values']['user-selected']); variable_set('term_block_range', $form_values['values']['term-selected']); }
表单现在可以正常保存数据。提交后值会保存在 Drupal 变量中(使用 variable_set),默认值则通过 variable_get 读取。
最后修改 hook_block_view(),使其从变量中读取标题和显示数量:
function sitemade_block_view($delta = ''){ $block = array(); switch ($delta){ case 1: $block['subject'] = variable_get('user_block', '用户'); $block['content'] = ''; $query = db_select('users', 'u') ->fields('u', array('uid', 'name')) ->orderBy('u.uid', 'DESC') ->range(0, variable_get('user_block_range', 5)) ->execute(); $users = $query->fetchAll(PDO::FETCH_ASSOC); foreach($users as $user){ $block['content'] .=''; } break; case 2: $block['subject'] = variable_get('node_block', '节点'); $block['content'] = ''; $query = db_select('node', 'n') ->fields('n', array('nid', 'title')) ->orderBy('n.nid', 'DESC') ->range(0, variable_get('node_block_range', 5)) ->execute(); $nodes = $query->fetchAll(PDO::FETCH_ASSOC); foreach($nodes as $node){ $block['content'] .=''; } break; case 3: $block['subject'] = variable_get('term_block', '术语'); $block['content'] = ''; $query = db_select('taxonomy_term_data', 't') ->fields('t', array('tid', 'name')) ->orderBy('t.tid', 'DESC') ->range(0, variable_get('term_block_range', 10)) ->execute(); $terms = $query->fetchAll(PDO::FETCH_ASSOC); foreach($terms as $term){ $block['content'] .=''; } break; } return $block; }
现在返回首页查看效果。别忘了最后一步 —— 清除缓存!