如何在Drupal自定义模块中重写Drag & Drop模块的pre_render函数?
遇到这种pre_render函数改不动的情况很常见,我来给你几个靠谱的解决方案,亲测在Drupal 9/10里管用:
可行解决方案
1. 替换元素类型的全局pre_render回调
Drupal的元素类型定义可以通过hook_element_info_alter修改,这是最通用的方法。你需要先找到原模块注册的元素类型(大概率是dragndrop_upload_element),然后替换它的#pre_render数组里的目标函数。
步骤如下:
- 在你的自定义模块里创建以下函数:
function YOUR_MODULE_element_info_alter(&$types) { // 定位到目标元素类型 if (isset($types['dragndrop_upload_element']['#pre_render'])) { foreach ($types['dragndrop_upload_element']['#pre_render'] as $key => $callback) { // 找到要替换的原函数 if ($callback === 'dragndrop_upload_element_element_pre_render') { // 替换成你的自定义函数 $types['dragndrop_upload_element']['#pre_render'][$key] = 'YOUR_MODULE_dnd_custom_pre_render'; break; } } } } // 你的自定义pre_render函数 function YOUR_MODULE_dnd_custom_pre_render($element) { // 先调用原模块的pre_render逻辑,保证原有功能正常 $element = dragndrop_upload_element_element_pre_render($element); // 这里添加你的自定义修改,比如修改元素属性、调整HTML结构等 // 举个例子:给元素加个自定义CSS类 if (isset($element['#attributes']['class'])) { $element['#attributes']['class'][] = 'my-custom-dnd-class'; } else { $element['#attributes']['class'] = ['my-custom-dnd-class']; } return $element; }
- 别忘了给你的模块设置更高的权重,确保你的修改能覆盖原模块的设置。在模块的
YOUR_MODULE.info.yml里加一行:
weight: 10
(原模块默认权重是0,10足够保证你的alter最后执行)
2. 针对特定表单修改pre_render回调
如果只需要修改某个特定表单里的上传元素,用hook_form_alter或者hook_form_FORM_ID_alter更精准:
function YOUR_MODULE_form_alter(&$form, &$form_state, $form_id) { // 替换成你要修改的表单ID,比如'node_article_form' if ($form_id === 'YOUR_TARGET_FORM_ID') { // 定位到表单里的上传元素,比如$form['field_your_upload_field'] if (isset($form['field_your_upload_field']['#pre_render'])) { foreach ($form['field_your_upload_field']['#pre_render'] as $key => $callback) { if ($callback === 'dragndrop_upload_element_element_pre_render') { $form['field_your_upload_field']['#pre_render'][$key] = 'YOUR_MODULE_dnd_custom_pre_render'; break; } } } } }
同样,你的自定义pre_render函数还是按上面的写法,先调用原函数再修改。
为什么你之前的方法没生效?
你试的dragndrop_upload_element_element_pre_render_alter这种钩子其实是不存在的——Drupal并没有为单个pre_render函数提供专门的alter钩子,只有针对元素信息或表单的通用alter。所以直接用这些不存在的钩子肯定没效果。
内容的提问来源于stack exchange,提问作者Brian Coolidge
相关产品推荐
相关产品推荐

