8

When implementing hook_field_extra_fields(), can I make the extra field hidden by default?

Sometimes it is friendlier to offer the extra fields as an option, instead of displaying it immediately after a module is enabled.

5

In _field_info_prepare_extra_fields() the extra fields are set to visible by default, but the extra field settings are stored in the field_bundle_settings variable which you can change in your module's hook_install() like:

$entity_type = 'node';
$bundle = 'article';
$field_name = 'my_extra_field';
$view_mode = 'teaser';

$field_bundle_setting = variable_get('field_bundle_settings', array());
$field_bundle_setting[$entity_type][$bundle]['extra_fields']['display'][$field_name][$view_mode]['visible'] = FALSE;
variable_set('field_bundle_settings', $field_bundle_setting);
| improve this answer | |
  • This didn't work for me - not sure why as clearly worked for the people who upvoted it. aklump's answer was the only solution that worked for me.. – Felix Eve Nov 17 '16 at 5:00
3

_field_extra_fields_pre_render(), the pre-render callback used by field_attach_form() and field_attach_view(), contains the following code:

  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'];
      }
    }
  }

Implementing hook_field_extra_fields_display_alter(), you can alter the visibility setting, but that would make the field not visible all the time the form is displayed. If you want not to show the field when the form is first loaded, and show it when, for example, another form field is selected or its value is changed, then you need to use some JavaScript code.

function mymodule_field_extra_fields_display_alter(&$displays, $context) {
  if ($context['entity_type'] == 'taxonomy_term' && $context['view_mode'] == 'full') {
    $displays['description']['visible'] = FALSE;
  }
}
| improve this answer | |
  • Maybe my question wasn't clear enough. I do want to show the extra field on the form (like admin/structure/types/manage/article/display/full) but I want the formatter select box to be set to <hidden> at first. – marcvangend Jul 5 '11 at 15:09
  • 2
    @marcvangend Then it's not possible with hook_field_extra_fields(). You can alter the form field, or alter the formatter used by the field, though. – kiamlaluno Jul 5 '11 at 15:18
  • OK, thanks. I'm not sure if altering the form will be easy, because of course I only want to set the formatter to hidden when the setting has not been explicitly set... I'll fiddle some more with it when I have more time. – marcvangend Jul 5 '11 at 15:38
2

There is a patch to add this ability to drupal core.

If you want to see this go in please review it and give feedback.

http://drupal.org/node/1256368#comment-7201552

| improve this answer | |
2

In the install hook of your module you can make a call to a function similiar this one and it will bulk hide your extra fields by default.

/**
 * Sets default visibility of extra fields in all active view modes on entity bundles.
 *
 * This will not overwrite visibility that already exists in the variable.
 *
 * @param  array $extra_field_names An array of extra fields
 * @param  string $entity_type       The name of the entity type. Defaults to 'node'.
 * @param  array $bundles           An array of bundle objects or names.
 */
function my_module_hide_extra_fields($extra_field_names, $entity_type = 'node', $bundles = NULL) {
  $entity_info = entity_get_info($entity_type);
  if ($bundles === NULL) {
    $bundles = array_keys($entity_info['bundles']);
  }

  foreach ($bundles as $bundle) {
    if (!is_string($bundle)) {
      $bundle = $bundle->type;
    }
    $settings = field_bundle_settings($entity_type, $bundle);

    $active_modes = array('default');
    foreach ($settings['view_modes'] as $mode => $mode_settings) {
      if ($mode_settings['custom_settings']) {
        $active_modes[] = $mode;
      }
    }
    foreach ($extra_field_names as $field_name) {
      foreach ($active_modes as $mode) {
        if (empty($settings['extra_fields']['display'][$field_name][$mode])
          || !array_key_exists('visible', $settings['extra_fields']['display'][$field_name][$mode])) {
          $settings['extra_fields']['display'][$field_name][$mode]['visible'] = FALSE;
          $settings['extra_fields']['display'][$field_name][$mode] += array(
            'weight' => 0, 
          );
        }
      }
    }
    field_bundle_settings($entity_type, $bundle, $settings);
  }
}
| improve this answer | |
  • 1
    This code works. You could run it as follows: my_module_hide_extra_fields(array('facebook_like_button', 'contact_link'), 'node', node_type_get_types()); – batigolix Sep 11 '14 at 18:47
-1

So much simpler example. For Drupal 7 Create example_module.install under the example_module directory

/**
 * hook_install
 */

function example_module_install() {
  $field_machine_name = 'new_extra_field';
  $entity_types = array('node', 'taxonomy_term', 'user'); 
  foreach ($entity_types as $type) {
    $info = entity_get_info($type);
    $settings = field_bundle_settings($type, $bundle);
    $view_modes = array_merge(array('default'), array_keys($info['view modes']));
    foreach($view_modes as $view_mode) {
      $settings['extra_fields']['display'][$field_machine_name][$view_mode] = array(
        'visible' => FALSE,
        'weight'  => 0,
      );
    }
    field_bundle_settings($type, $bundle, $settings);
  }
}

Documentation for hook_install https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_install/7

In your example_module.module file add

 /**
  * Implementation of hook_field_extra_fields
  *
  */
 function example_module_field_extra_fields() {
   $extra = array();
   $field_machine_name = 'new_extra_field';
   $entity_types = array('node', 'taxonomy_term', 'user'); 
   foreach ($entity_types as $type) {
     $info = entity_get_info($type);
     foreach(array_keys($info["bundles"]) as $bundle) {
       $extra[$type][$bundle]['display'][$field_machine_name] = array(
         'label' => t('New extra field that will show up in manage display'),
         'description' => 'A description for the extra field',
         'weight' => 5,
        );
     }
   }
   return $extra; 
 }

Documentation for hook_field_extra_fields https://api.drupal.org/api/drupal/modules%21field%21field.api.php/function/hook_field_extra_fields/7

| improve this answer | |
  • I did not manage to get this code working. $view_modes werent declared correctly (i fixed that in the snippet above), and the $bundle variable isnt set – batigolix Sep 11 '14 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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