D9节点显示UI无法启用字段或分配区域 如何编程实现配置
Drupal 9 节点视图/表单显示配置编程配置方案
你遇到的后台配置页转圈、保存后字段恢复禁用的问题,绝大多数情况不是缓存问题,是站点字段量太大,提交表单时超过PHP max_input_vars 配置的默认上限(通常默认值为1000),导致提交参数丢失、配置保存回滚,临时解决可以把php.ini里该参数调到3000及以上;需要批量部署配置可以直接用实体显示API写入,比直接改数据库安全可靠。
现有代码的错误修正
你提供的代码有3个会导致保存失效的问题:
- 视图显示配置里误用了表单组件类型:
string_textfield是表单编辑页用的输入控件(Widget),不是前端视图渲染用的格式化器(Formatter),普通文本字段对应视图格式化器是string,用错类型会触发配置校验失败,字段自动归为禁用状态。 - 给
full视图模式设置字段时没有传region参数,未指定区域的字段会被系统自动放到禁用区。 - 代码中占位符
node_type、field_name需要替换为你站点实际的内容类型机器名、字段机器名。
修正后的可运行代码示例:
/** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository **/ $display_repository = \Drupal::service('entity_display.repository'); // 配置默认表单模式的字段控件 $display_repository->getFormDisplay('node', '你的内容类型机器名') ->setComponent('你的字段机器名', [ 'type' => 'string_textfield', // 表单模式才用textfield类控件 'region' => 'content', 'weight' => 10, // 可选,设置字段排序权重,数字越小越靠前 ]) ->save(); // 配置默认视图模式的字段显示 $display_repository->getViewDisplay('node', '你的内容类型机器名') ->setComponent('你的字段机器名', [ 'label' => 'hidden', 'type' => 'string', // 视图模式用对应字段类型的格式化器 'region' => 'content', 'weight' => 10, ]) ->save(); // 配置full视图模式的字段显示 $display_repository->getViewDisplay('node', '你的内容类型机器名', 'full') ->setComponent('你的字段机器名', [ 'label' => 'hidden', 'type' => 'string', 'region' => 'content', // 必须指定region为content才会在前端显示 'weight' => 10, ]) ->save();
如果需要批量配置多个字段,把字段配置放到数组里循环调用setComponent即可。
代码执行方式
不要用常规的请求级钩子执行这类配置逻辑:这类配置是一次性写入的持久化配置,放到hook_init、hook_entity_view_alter这类每次请求都会执行的钩子会重复写入配置,严重拖慢站点性能。推荐两种执行方式:
- 生产环境部署:把代码写到自定义模块的
hook_install()(模块首次安装时执行)或者hook_update_N()(模块更新函数,执行drush updatedb时触发)里,执行一次后配置就会永久写入系统配置,符合Drupal配置同步的最佳实践。 - 临时调试:安装Devel模块后,通过模块提供的「执行PHP代码」功能把代码跑一遍,跑完清除站点缓存即可生效,不需要把代码写到站点常驻逻辑里。
不推荐直接操作数据库修改配置:实体显示配置存在
config数据表中,存储格式为序列化的YAML文本,手动修改很容易出现格式错误导致站点报错,用官方提供的实体API写入会自动校验配置格式、触发必要的钩子和缓存清理,稳定性更高。
内容的提问来源于stack exchange,提问作者nschildre
相关产品推荐
相关产品推荐

