function content_field in Content Construction Kit (CCK) 6
Same name and namespace in other branches
- 5 content.module \content_field()
- 6.3 content.module \content_field()
- 6.2 content.module \content_field()
Implementation of hook_field(). Handles common field housekeeping.
This implementation is special, as content.module does not define any field types. Instead, this function gets called after the type-specific hook, and takes care of default stuff common to all field types.
Db-storage ops ('load', 'insert', 'update', 'delete', 'delete revisions') are not executed field by field, and are thus handled separately in content_storage.
The 'view' operation constructs the $node in a way that you can use drupal_render() to display the formatted output for an individual field. i.e. print drupal_render($node->field_foo);
The code now supports both single value formatters, which theme an individual item value as has been done in previous version of CCK, and multiple value formatters, which theme all values for the field in a single theme. The multiple value formatters could be used, for instance, to plot field values on a single map or display them in a graph. Single value formatters are the default, multiple value formatters can be designated as such in formatter_info().
The node array will look like: $node->content['field_foo'] = array( '#type' => 'content_field_view', '#title' => 'label' '#field_name' => 'field_name', '#node' => $node, 'items' => 0 => array( '#item' => $items[0], // Only for 'single-value' formatters '#theme' => $theme, '#field_name' => 'field_name', '#type_name' => $node->type, '#formatter' => $formatter_name, ), 1 => array( '#item' => $items[1], // Only for 'single-value' formatters '#theme' => $theme, '#field_name' => 'field_name', '#type_name' => $node->type, '#formatter' => $formatter_name, ), // Only for 'multiple-value' formatters '#theme' => $theme, '#field_name' => 'field_name', '#type_name' => $node->type, '#formatter' => $formatter_name, ), );
1 call to content_field()
- _content_field_invoke_default in ./
content.module - Invoke content.module's version of a field hook.
File
- ./
content.module, line 637 - Allows administrators to associate custom fields to content types.
Code
function content_field($op, &$node, $field, &$items, $teaser, $page) {
switch ($op) {
case 'validate':
// TODO : here we could validate that the number of multiple data is correct ?
// We're controlling the number of fields to fill out and saving empty
// ones if a specified number is requested, so no reason to do any validation
// here right now, but if later create a method to indicate whether
// 'required' means all values must be filled out, we can come back
// here and check that they're not empty.
break;
case 'presave':
// Manual node_save calls might not have all fields filled in.
// On node insert, we need to make sure all tables get at least an empty
// record, or subsequent edits, using drupal_write_record() in update mode,
// won't insert any data.
// Missing fields on node update are handled in content_storage().
if (empty($items) && !isset($node->nid)) {
foreach (array_keys($field['columns']) as $column) {
$items[0][$column] = NULL;
}
$node->{$field}['field_name'] = $items;
}
// If there was an AHAH add more button in this field, don't save it.
// TODO : is it still needed ?
unset($items[$field['field_name'] . '_add_more']);
// If content module is handling multiple values, don't save empty items.
if (content_handle('widget', 'multiple values', $field) == CONTENT_HANDLE_CORE) {
// Filter out empty values.
$items = content_set_empty($field, $items);
// Reorder items to account for drag-n-drop reordering.
$items = _content_sort_items($field, $items);
}
break;
case 'view':
$element = array();
if ($node->build_mode == NODE_BUILD_NORMAL) {
$context = $teaser ? 'teaser' : 'full';
}
else {
$context = $node->build_mode;
}
// Do not include field labels when indexing content.
if ($context == NODE_BUILD_SEARCH_INDEX) {
$field['display_settings']['label']['format'] = 'hidden';
}
$field_types = _content_field_types();
$formatters = $field_types[$field['type']]['formatters'];
$formatter_name = isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
if (!isset($formatters[$formatter_name]) && $formatter_name != 'hidden') {
// This might happen when the selected formatter has been renamed in the
// module, or if the module has been disabled since then.
$formatter_name = 'default';
}
if (isset($formatters[$formatter_name])) {
$formatter = $formatters[$formatter_name];
$theme = $formatter['module'] . '_formatter_' . $formatter_name;
$single = content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE;
$element = array(
'#type' => 'content_field_view',
'#title' => $field['widget']['label'],
'#weight' => $field['widget']['weight'],
'#field_name' => $field['field_name'],
'#access' => $formatter_name != 'hidden',
'#node' => $node,
'#teaser' => $teaser,
'#page' => $page,
'#single' => $single,
'items' => array(),
);
// Fill-in items.
foreach ($items as $delta => $item) {
$element['items'][$delta] = array(
'#item' => $item,
'#weight' => $delta,
);
}
// Append formatter information either on each item ('single-value' formatter)
// or at the upper 'items' level ('multiple-value' formatter)
$format_info = array(
'#theme' => $theme,
'#field_name' => $field['field_name'],
'#type_name' => $node->type,
'#formatter' => $formatter_name,
);
if ($single) {
foreach ($items as $delta => $item) {
$element['items'][$delta] += $format_info;
}
}
else {
$element['items'] += $format_info;
}
}
return array(
$field['field_name'] => $element,
);
case 'alter':
// Add back the formatted values in the 'view' element,
// so that node templates can use it.
if (isset($node->content[$field['field_name']])) {
$element = $node->content[$field['field_name']];
if ($element['#single']) {
// Single value formatter.
foreach (element_children($element['items']) as $delta) {
// Use isset() to avoid undefined index message on #children when field values are empty.
$items[$delta]['view'] = isset($element['items'][$delta]['#children']) ? $element['items'][$delta]['#children'] : '';
}
}
else {
// Multiple values formatter.
$items[0]['view'] = $element['items']['#children'];
}
}
else {
$items[0]['view'] = '';
}
break;
case 'prepare translation':
$addition = array();
if (isset($node->translation_source->{$field}['field_name'])) {
$addition[$field['field_name']] = $node->translation_source->{$field}['field_name'];
}
return $addition;
}
}