You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 06:55:33