在Drupal 7中更改文件表单字段元素
借助字符串覆盖等功能,您可以在整个站点中替换字符串的所有实例,因此在Drupal7中更改文本非常简单。如果要更改单个表单上的单个元素,则字符串覆盖不是很有效,但是使用hook_form_alter()或hook_form_form-id_alter()允许您在Drupal站点中操作任何表单。
首先,在节点表单上更改文件字段表单元素似乎很简单,但是实际情况要复杂一些。假设我们有一个名为“page”的内容类型,其中包含一个名为“field_page_image”的元素,这只是一个默认文件字段。在此示例中,我创建了一个无限列表,但是该代码将适用于一定数量的项目,甚至一个。设置一个hook_form_form-id_alter()函数来更改节点编辑表单很容易,但是您会很快意识到,尽管存在field_page_image字段,但是与文件本身相关的元素却不存在。这是因为这些元素是在此函数调用之后构建的。
要更改这些字段,我们需要使用#after_build属性。此属性包含一个函数名称数组,这些函数名称将在构建form或form元素后调用。由于尚未创建文件字段的表单元素,因此必须在构建完之后使用此属性来更改元素。
由于我要更改的节点类型编辑表单是针对节点类型“页面”的,因此挂钩函数称为“mymodule_form_page_node_form_alter()”。创建此函数后,我仅循环浏览“field_page_image”元素中的元素,并将#after_build属性添加到每个文件元素中。该函数mymodule_rename_remove_button()用于更改各个元素,因此我仅在此处添加函数名称。
我们可以放心地忽略任何非数字元素,因为这些只是元元素,详细说明了“选择文件”按钮周围应显示的文字。这是该mymodule_form_page_node_form_alter()函数的源代码。
function mymodule_form_page_node_form_alter(&$form, &$form_state) { if (isset($form['#node']->language)) { $node_language = $form['#node']->language; if (isset($form['field_page_image'][$node_language])) { foreach ($form['field_page_image'][$node_language] as $item => $field_banner) { if (!is_numeric($item)) { continue; } if (isset($form['field_page_image'][$node_language][$item])) { //构建完文件字段元素后,对其进行更改。 $form['field_page_image'][$node_language][$item]['#after_build'][] = 'mymodule_rename_remove_button'; } } } } }
现在剩下的就是创建mymodule_rename_remove_button()函数了。此函数将元素和表单状态作为参数,并且必须返回更改后的表单元素。要更改删除文件的按钮的文本,我们只需要执行以下操作。
function mymodule_rename_remove_button($element, &$form_state) { $element['remove_button']['#value'] = t('Remove/Replace'); return $element; }
现在,我们上传到此内容类型的所有文件都将通过“删除/替换”按钮显示在节点编辑页面上。
除了此处提到的情况外,#after_build属性可以在多种不同的情况下使用。一个很好的例子是,当试图改变一种形式,然后又被另一个为其添加更多元素的模块所改变时。通过在主表单元素上使用#after_build,可以确保在所有模块都处理完表单后可以对其进行更改。这意味着您不必依赖模块加载优先级,如果在添加某些元素之前尝试更改表单,则可能导致问题。