我的模块实现了一系列字段api函数,以便提供由文本字段和textarea组成的自定义字段类型。 hook_field_validate函数使用所有正确的键调用,但从不调用任何值 - 如果有人查看所有代码并告诉我是否有任何问题,我会非常感激。
function brooklands_field_info() {
return array(
'brooklands_heading_text' => array(
'label' => t('Heading with text'),
'description' => t('Heading with text - says it all.'),
'default_widget' => 'brooklands_heading_text_widget',
'default_formatter' => 'brooklands_heading_text_formatter',
),
);
}
function brooklands_field_validate($entity_type, $entity, $field,
$instance, $langcode, $items, &$errors) {
/*foreach ($items as $delta => $item) {
// $item never contains any data!!!!!
$heading = check_plain($item['brooklandsheading']);
$text = check_markup($item['value'], $item['format']);
if(!empty($heading) || !empty($text) && empty($heading) || empty($text)) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'brooklands_invalid',
'message' => t('Must have both heading and text'),
);
}
}*/
}
function brooklands_field_widget_error($element, $error, $form, &$form_state) {
switch ($error['error']) {
case 'brooklands_invalid':
form_error($element, $error['message']);
break;
}
}
function brooklands_field_is_empty($item, $field) {
return empty($item['brooklandsheading']) || empty($item['value']);
}
function brooklands_field_formatter_info() {
return array(
'brooklands_heading_text_formatter' => array(
'label' => t('Heading text formatter'),
'field types' => array('brooklands_heading_text'),
),
);
}
function brooklands_field_formatter_view($entity_type, $entity, $field,
$instance, $langcode, $items, $display) {
$element = array();
foreach ($items as $delta => $item) {
$element[$delta]['#markup'] = '<div class="brooklands-heading-text"><h3>'
.check_plain($item['brooklandsheading']).'</h3>'
.check_markup($item['value'], $item['format']).'</div>';
}
return $element;
}
function brooklands_field_widget_info() {
return array(
'brooklands_heading_text_widget' => array(
'label' => 'Heading/text widget',
'field types' => array('brooklands_heading_text'),
),
);
}
function brooklands_field_widget_form(&$form, &$form_state, $field,
$instance, $langcode, $items, $delta, $element) {
$element['brooklandsheading'] = array(
'#delta' => $delta,
'#default_value' => isset($items[$delta]['brooklandsheading']) ?
$items[$delta]['brooklandsheading'] : '',
'#type' => 'textfield',
'#size' => 64,
'#maxlength' => 256,
'#title' => t('Heading')
);
$text = array(
'#type' => 'textarea',
'#default_value' => isset($items[$delta]['value']) ?
$items[$delta]['value'] : '',
);
$element += $text;
$element['#format'] = isset($items[$delta]['format']) ?
$items[$delta]['format'] : NULL;
$element['#base_type'] = $element['#type'];
$element['#type'] = 'text_format';
$element['#title'] = t('Text');
return $element;
}
编辑:这是我模块的安装文件中的hook_field_schema实现 -
function brooklands_field_schema($field) {
$columns = array(
'brooklandsheading' => array(
'type' => 'varchar',
'length' => 256,
'not null' => FALSE
),
'value' => array(
'type' => 'text',
'not null' => FALSE
),
'format' => array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
),
);
return array(
'columns' => $columns,
'indexes' => array(
'format' => array('format'),
),
'foreign keys' => array(
'format' => array(
'table' => 'filter_format',
'columns' => array('format' => 'format'),
),
),
);
}
答案 0 :(得分:0)
我发现这段代码有点令人困惑,我不是专家,但我只是努力解决并解决了类似的问题,我觉得这个问题至少值得为记录提供一个谨慎的部分答案。
我理解它,表单通过循环并呈现$ element数组生成,并且它计算出如何通过数组中每个项的键将结果输入与模式匹配。
所以,我这里立刻看错了的是,架构设置了3种类型的数据来存储:'brooklandsheading','value'和'format',所以我期待$ element数组使用$ element ['brooklandsheading']定义文本字段,$ element ['value']定义文本区域,$ element ['format']定义另一个文本字段。
(令人困惑的名字,顺便说一句!我个人不会使用'value'和'format',以避免与['#value']和格式化程序混淆)
这段代码的一个问题是,它正在将应该映射到['value']的表单插入到没有['value']键的$ element上。我无法看到表单如何知道将哪个列提供给它。
我真的不知道['#format']发生了什么,说实话,它看起来并不正确,但我无法弄清楚它正在尝试做什么。
因此,对于此代码,我立即建议将$text = array( '#type' => 'textarea', ...
替换为$element['value'] = array( ' '#type' => 'textarea',
至于为什么$ element ['brooklandsheading']没有通过,没有任何东西在代码中跳出错误,所以我怀疑它可能是因为另一个小'gotcha':在hook__field_schema中更改模式后( ),您必须删除该字段的所有实例,然后禁用,然后从模块中完全卸载模块 - &gt;卸载选项卡,然后重新启用该模块并重新创建所有字段。要应用更改的模式,Drupal需要从数据库中删除并重新创建表,Drupal不会这样做,除非它确定它不会破坏有价值的数据。