Take the 2-minute tour ×
Drupal Answers is a question and answer site for Drupal developers and administrators. It's 100% free, no registration required.

I just found out about hook_field_extra_fields(), but the documentation doesn't really tell me how to use it. Where is the extra-fields output generated? I tried hard to understand the Node and Poll modules, but I can't figure it out. I also tried to add a custom field formatter.

Do you have any hint? All information I googled simply skips the view-related part.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

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;
}
share|improve this answer
    
Thanks you a lot for the explanation, but I don't yet understand where the extra field's output (or form element) is built. (By where, I mean the hook/function/whatever in the source code.) In my case, I've got some arbitrary data, loosely correlated to nodes, soaring in another subsystem, which i want to expose as fields to display modes. I thought these extra fields are the way to go? Or am I wrong? –  Philipp Melab Sep 4 '11 at 5:39
    
hook_field_extra_fields() is used to allow administrator users to change the order in which fields are rendered, or shown in the edit form. Normally, any module implementing fields implements that hook too. –  kiamlaluno Sep 4 '11 at 9:19
    
Now I got it! I was searching for some display hook for my extra field. But I simply have to add it in hook_entity_view_alter or similar, right? Thank you for bumping me in the right direction! –  Philipp Melab Sep 4 '11 at 9:50
    
_field_extra_fields_pre_render() is a pre-render function, which means it alters the form array right before it is rendered; if your field is not implemented using the field API, you just need to add it to the node edit form, as you usually do. If it is a field implemented using field API, then you don't need to do anything more; the field will be added to the node if you implement all the functions required from the field API. –  kiamlaluno Sep 4 '11 at 10:05
add comment

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>',
    );
  }
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.