Drupal 7自定义表单依赖及单内容类型多表单工作流配置问询
我来分享下在Drupal 7里实现这个需求的实操方案,我之前做过类似的场景,亲测有效~
实现Drupal 7单内容类型多表单(对应不同工作流与字段集)
核心思路
核心就是通过自定义模块路由不同的表单URL,为每个URL生成对应内容类型的表单实例,然后动态调整表单字段、绑定专属的提交处理逻辑(也就是不同工作流)。
具体实现步骤
1. 注册自定义表单路由
在你的自定义模块的.module文件里,用hook_menu()定义各个表单的URL路径,比如:
function my_custom_module_menu() { $items = array(); // 表单1路由 $items['form1'] = array( 'title' => '表单1:工作流1', 'page callback' => 'drupal_get_form', 'page arguments' => array('my_custom_module_form1'), 'access arguments' => array('create my_content_type content'), // 对应内容类型的创建权限 'type' => MENU_CALLBACK, ); // 表单2路由 $items['form2'] = array( 'title' => '表单2:工作流2', 'page callback' => 'drupal_get_form', 'page arguments' => array('my_custom_module_form2'), 'access arguments' => array('create my_content_type content'), 'type' => MENU_CALLBACK, ); // 表单3同理,复制上面的结构修改参数即可 return $items; }
2. 生成对应表单实例(基于目标内容类型)
每个表单函数都基于内容类型的默认节点表单构建,然后动态移除不需要的字段:
function my_custom_module_form1($form, &$form_state) { // 加载目标内容类型的默认节点表单 $node = (object) array('type' => 'my_content_type'); node_object_prepare($node); $form = drupal_get_form('my_content_type_node_form', $node); // 只保留需要的字段(a、b、e、f、g) $keep_fields = array('field_a', 'field_b', 'field_e', 'field_f', 'field_g'); foreach ($form as $key => $element) { if (strpos($key, 'field_') === 0 && !in_array($key, $keep_fields)) { unset($form[$key]); } } // 替换表单的提交处理函数,绑定工作流1的逻辑 $form['actions']['submit']['#submit'] = array('my_custom_module_form1_submit'); return $form; } // 表单2的函数同理,调整保留字段和提交处理函数 function my_custom_module_form2($form, &$form_state) { $node = (object) array('type' => 'my_content_type'); node_object_prepare($node); $form = drupal_get_form('my_content_type_node_form', $node); $keep_fields = array('field_a', 'field_b', 'field_c', 'field_e', 'field_h'); foreach ($form as $key => $element) { if (strpos($key, 'field_') === 0 && !in_array($key, $keep_fields)) { unset($form[$key]); } } $form['actions']['submit']['#submit'] = array('my_custom_module_form2_submit'); return $form; }
3. 实现各表单的专属工作流逻辑
在提交处理函数里,完成节点保存后触发对应的工作流(比如更新状态、调用Rules规则、发送通知等):
function my_custom_module_form1_submit($form, &$form_state) { // 先执行默认的节点保存逻辑 node_form_submit($form, $form_state); $node = $form_state['node']; // 触发工作流1:比如更新节点工作流状态 $node->field_workflow_status['und'][0]['value'] = 'workflow1_started'; node_save($node); // 其他工作流操作,比如发送邮件通知、创建关联实体等 // ... } function my_custom_module_form2_submit($form, &$form_state) { node_form_submit($form, $form_state); $node = $form_state['node']; // 触发工作流2 $node->field_workflow_status['und'][0]['value'] = 'workflow2_started'; node_save($node); // 专属工作流操作 // ... }
4. 优化与注意事项
- 字段权限:如果某些字段需要额外权限控制,可以在表单函数里通过
#access属性设置,比如$form['field_f']['#access'] = user_access('access field f'); - 表单验证:需要自定义验证逻辑的话,添加
$form['#validate'][] = 'my_custom_module_form1_validate';即可 - URL友好化:可以在Drupal后台「配置 > 搜索和元数据 > URL别名」里给
form1等路径设置更友好的别名 - 缓存问题:如果表单字段有动态变化,记得在
hook_menu()里加'cache' => FALSE,避免缓存导致字段显示异常
替代方案(减少重复代码)
如果不想写太多重复代码,可以把表单逻辑抽象成通用函数,通过URL参数区分不同表单配置:
// 路由改成带参数的形式 $items['custom-form/%'] = array( 'title' => '自定义内容表单', 'page callback' => 'my_custom_module_generic_form', 'page arguments' => array(1), 'access arguments' => array('create my_content_type content'), 'type' => MENU_CALLBACK, ); // 通用表单函数 function my_custom_module_generic_form($form, &$form_state, $form_key) { // 定义各个表单的配置数组 $form_configs = array( 'form1' => array( 'keep_fields' => array('field_a', 'field_b', 'field_e', 'field_f', 'field_g'), 'submit_callback' => 'my_custom_module_form1_submit', ), 'form2' => array( 'keep_fields' => array('field_a', 'field_b', 'field_c', 'field_e', 'field_h'), 'submit_callback' => 'my_custom_module_form2_submit', ), ); if (!isset($form_configs[$form_key])) { drupal_not_found(); exit; } $config = $form_configs[$form_key]; $node = (object) array('type' => 'my_content_type'); node_object_prepare($node); $form = drupal_get_form('my_content_type_node_form', $node); // 过滤字段 foreach ($form as $key => $element) { if (strpos($key, 'field_') === 0 && !in_array($key, $config['keep_fields'])) { unset($form[$key]); } } // 设置提交回调 $form['actions']['submit']['#submit'] = array($config['submit_callback']); return $form; }
这样后续新增表单只需要在$form_configs里添加配置即可,维护起来更省心。
内容的提问来源于stack exchange,提问作者SciMeg
相关产品推荐
相关产品推荐

