Drupal - How should I use hook_field_extra_fields()?
This is a simple example showing how to add an additional field to the Field UI and provides an example of one way of inserting the field onto a node.
/**
* Implements hook_field_extra_fields().
*/
function MODULE_field_extra_fields() {
$extra['node']['article']['display']['extended_submitted_by'] = array(
'label' => t('Extended Submitted By'),
'description' => t('Provides Jumper Menu for Version Selection'),
'weight' => 0,
);
return $extra;
}
/**
* Implements hook_node_view().
*/
function MODULE_node_view($node, $view_mode, $langcode) {
// Only add if the view mode is for a full view, although we
// could control this via the Field UI too using 'hidden'.
if ($view_mode == 'full' && $node->type == 'article') {
$node->content['extended_submitted_by'] = array(
'#markup' => '<p>This is inserted unless hidden in the field ui.</p>',
);
}
}
hook_field_extra_fields()
is invoked by _field_extra_fields_pre_render(), which is a pre-render function used by field_attach_form(), and field_attach_view().
/**
* Pre-render callback to adjust weights and visibility of non-field elements.
*/
function _field_extra_fields_pre_render($elements) {
$entity_type = $elements['#entity_type'];
$bundle = $elements['#bundle'];
if (isset($elements['#type']) && $elements['#type'] == 'form') {
$extra_fields = field_info_extra_fields($entity_type, $bundle, 'form');
foreach ($extra_fields as $name => $settings) {
if (isset($elements[$name])) {
$elements[$name]['#weight'] = $settings['weight'];
}
}
}
elseif (isset($elements['#view_mode'])) {
$view_mode = $elements['#view_mode'];
$extra_fields = field_extra_fields_get_display($entity_type, $bundle, $view_mode);
foreach ($extra_fields as $name => $settings) {
if (isset($elements[$name])) {
$elements[$name]['#weight'] = $settings['weight'];
// Visibility: make sure we do not accidentally show a hidden element.
$elements[$name]['#access'] = isset($elements[$name]['#access']) ? ($elements[$name]['#access'] && $settings['visible']) : $settings['visible'];
}
}
}
return $elements;
}
Using those functions, you should not invoke the hook directly. Those functions are already used for entities that Drupal knows; if you are implementing a field for nodes, all you need to do is implementing the hook.
An example of hook_field_extra_fields()
implementation is mollom_field_extra_fields().
function mollom_field_extra_fields() {
$extras = array();
$forms = array_flip(db_query('SELECT form_id FROM {mollom_form}')->fetchCol());
foreach (mollom_form_list() as $form_id => $info) {
// @todo Technically, an 'entity' does not need to be a Entity/Field API
// kind of entity. Ideally of course, developers should use fieldable
// entities, but contributed/custom code may not. It is not clear whether
// registering extra fields for non-existing entities/bundles can break
// anything, so leaving it this way for now.
if (isset($info['entity']) && isset($forms[$form_id])) {
// If the entity type does not implement bundles, then entity_get_info()
// assumes a single bundle named after the entity.
$entity_type = $info['entity'];
$bundle = (isset($info['bundle']) ? $info['bundle'] : $entity_type);
$extras[$entity_type][$bundle]['form']['mollom'] = array(
'label' => t('Mollom'),
'description' => t('Mollom CAPTCHA or privacy policy link'),
'weight' => 99,
);
}
}
return $extras;
}
The effect of that code is allowing administrator users to change the order in which fields are rendered when the entity is rendered, or shown in the edit form, when the entity is edited. The Field UI module expose a UI that allows users with the right permission (usually administrator users) to sort those false fields.