How should I display labels of empty fields when viewing node?
In content-field.tpl.php at CCK module there was:
if (!$field_empty) :
but this IF statement is not in field.tpl.php in drupal7.
i also tried function

function MYTHEME_preprocess_field(&$variables, $hook) {
  dpm($variables);
}

but this is not run for empty fields.

I do not want it in node.tpl.php - too much work, needs to be updated with each new field and i have fields in fieldsets. I want it globally (with respecting "Display fields" at content type).

Not important if i can do that in theme or in module.

I found only issues "how to NOT display label...".

Comments

StuartDH’s picture

Did you ever find a solution to this? I've been looking for quite a while and can't find out how to display the labels for empty fields, which could then help prompt users to fill in the blanks on a page.

Everett Zufelt’s picture

Status: Active » Needs review

http://ygerasimov.com/show-empty-fields

Haven't tested, but it seems right. Please set to Fixed if this resolves the issue.

chrylarson’s picture

Version: 7.8 » 7.12

I can confirm that the link in #2 worked for me. I created a custom module with the code and enabled it.

<?php
/**
 * Implements hook_field_attach_view_alter().
 *
 * Show titles of empty fields.
 */
function example_field_attach_view_alter(&$output, $context) {
  // We proceed only on nodes.
  if ($context['entity_type'] != 'node' || $context['view_mode'] != 'full') {
    return;
  }
 
  $node = $context['entity'];
  // Load all instances of the fields for the node.
  $instances = _field_invoke_get_instances('node', $node->type, array('default' => TRUE, 'deleted' => FALSE));
 
  foreach ($instances as $field_name => $instance) {
    // Set content for fields they are empty.
    if (empty($node->{$field_name})) {
      $display = field_get_display($instance, 'full', $node);
      // Do not add field that is hidden in current display.
      if ($display['type'] == 'hidden') {
        continue;
      }
      // Load field settings.
      $field = field_info_field($field_name);
      // Set output for field.
      $output[$field_name] = array(
        '#theme' => 'field',
        '#title' => $instance['label'],
        '#label_display' => 'above',
        '#field_type' => $field['type'],
        '#field_name' => $field_name,
        '#bundle' => $node->type,
        '#object' => $node,
        '#items' => array(),
        '#entity_type' => 'node',
        '#weight' => $display['weight'],
        0 => array('#markup' => '&nbsp;'),
      );
    }
  }
}
?>
Anonymous’s picture

This worked as I'd hoped and now the labels for empty fields are displaying.

In case there are people even newer than me needing this fix, here's what I did to implement:

1. Copied the above code into a file called dispempty.module
2. Changed function example_field_attach_view_alter to function dispempty_field_attach_view_alter
3. Created a file called dispempty.info containing:
name = Display Empty Fields
description = Displays empty fields in forms
core = 7.x
4. Put both files into /sites/all/modules/dispempty
5. Enabled the Display Empty Fields module in Modules - it appeared in the Other section.

I'm not sure whether (2) is necessary - perhaps someone could confirm.

I'm REALLY surprised to see that there is no field display option to cover this from the UI!

Thanks a lot to ygerasimov for making this available!

Alan D.’s picture

Status: Closed (fixed) » Fixed

I've made a sandbox project that does this: http://drupal.org/sandbox/aland/1658254

It defines new formatter settings that enable administrators to show either "<none>" or a custom string.

This is customisable per instance per view mode.

[update]
http://drupal.org/project/empty_fields

Version: 7.12 » 7.x-dev
Status: Needs review » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

mattc321’s picture

Issue summary: View changes

This works however breaks editable fields and exposed inline entity forms.

Luckily they have a display type of editable, so you can check for them and continue the foreach if they are editable.

Show labels for empty fields without breaking exposed editable fields or inline entity forms

/**
 * Implements hook_field_attach_view_alter().
 *
 * Show titles of empty fields.
 */
function YOUR_MODULE_field_attach_view_alter(&$output, $context) {
	
  // We proceed only on nodes.

  if ($context['entity_type'] != 'node' || $context['view_mode'] != 'full') {
    return;
  } 
  $node = $context['entity'];
  // Load all instances of the fields for the node.
  $instances = _field_invoke_get_instances('node', $node->type, array('default' => TRUE, 'deleted' => FALSE));
 
  foreach ($instances as $field_name => $instance) {
    // Set content for fields they are empty.
    if (empty($node->{$field_name})) {
      $display = field_get_display($instance, 'full', $node);
	
      // Do not add field that is hidden in current display.
      if ($display['type'] == 'hidden') {
        continue;
      } //set display type on inline entity forms to editable to get this display type
      if ($display['type'] == 'editable') {
        continue;
      }
      // Load field settings.
      $field = field_info_field($field_name);
      // Set output for field.
      $output[$field_name] = array(
        '#theme' => 'field',
        '#title' => $instance['label'],
        '#label_display' => 'above',
        '#field_type' => $field['type'],
        '#field_name' => $field_name,
        '#bundle' => $node->type,
        '#object' => $node,
        '#items' => array(),
        '#entity_type' => 'node',
        '#weight' => $display['weight'],
        0 => array('#markup' => '&nbsp;'),
      );
    }
  }
}
cbrody’s picture

Thanks mattc321, very useful. Trying to get the empty fields to print their associated allowed_values below the label, but without success -- any ideas?

mattc321’s picture

Hey cbrody, this is untested, but this is one way you could try. The only problem is that you would want some sort of IF statement, because you likely don't want to fetch the allowed values on every single empty field. For testing purposes though.

<?php

...

$all_fields_on_my_website = field_info_fields();
$allowed_values= list_allowed_values($all_fields_on_my_website[$field_name"]);

// now $allowed_values is an array of allowed values for your field

foreach($allowed_values as $key => $allowed) { 
    $str_allows_values .= $allowed.', ';   //build a string out of the array
}

      // Load field settings.
      $field = field_info_field($field_name);
      // Set output for field.
      $output[$field_name] = array(
        '#theme' => 'field',
        '#title' => $instance['label'],
        '#label_display' => 'above',
        '#field_type' => $field['type'],
        '#field_name' => $field_name,
        '#bundle' => $node->type,
        '#object' => $node,
        '#items' => array(),
        '#entity_type' => 'node',
        '#weight' => $display['weight'],
        0 => array('#markup' => '&nbsp;'),
        '#suffix' => '<div class="my-allowed-values">'.$str_allows_values.'</div>',//new line
      );

...
?>
cbrody’s picture

WIth a couple minor modifications that works great, thanks.

ugintl’s picture

There is an option to add default text to the field in the field settings. So that it appears on the page even if user hasn't added text to it, but it is not working. Has anybody tried it? I am also using editable module.

ugintl’s picture

Installed the module from #8. Nothing happening nothing showing

GuyPaddock’s picture

An additional note in case it helps anyone else out: In our case, we wanted to put in a placeholder value ("Information needed") for any fields we were rendering like this. If you have a similar requirement, you will likely need to make sure you populate the '#items' array as well.

For example:

      $entity_type = $context['entity_type'];
      $view_mode   = $context['view_mode'];
      $default_text = t('Information needed');

      // Set output for field.
      $output[$field_name] = array(
        '#theme'          => 'field',
        '#weight'         => $display['weight'],
        '#title'          => $instance['label'],
        '#access'         => TRUE,
        '#label_display'  => 'inline',
        '#view_mode'      => $view_mode,
        '#language'       => LANGUAGE_NONE,
        '#field_name'     => $field_name,
        '#field_type'     => $field['type'],
        '#entity_type'    => $entity_type,
        '#bundle'         => $node->type,
        '#object'         => $node,
        '#formatter'      => 'text_plain',
        '#items'          => array(
          0 => array(
            'value'       => $default_text,
          )
        ),
        0 => array(
          '#markup' => '<em>' . $default_text . '</em>',
        ),
      );
GuyPaddock’s picture

Also, it's probably best to let Drupal tell you if the field value is empty instead of trying to check the node object directly. Different field types map to entities in different ways -- there's not always a 1:1 mapping from field name to node object.

So instead of this:

    if (empty($node->{$field_name})) {
      // ...
    }

Use this:

    $field_value = field_get_items('node', $node, $field_name);

    // Set content for fields they are empty.
    if (empty($field_value)) {
      // ...
    }
capysara’s picture

Thanks all!

I used #8, #14, and #15 and it worked perfectly!

Also, if you're not into custom coding, the empty fields module, noted above, is great, but I didn't want to install 2 extra modules for just a couple of fields.

saki_rayogram’s picture

The above solutions didn't work for me on Drupal 8, but I downloaded the Empty Fields module and adapted its code to automatically show for every empty field, instead of having to enable it on hundred of fields:

<?php

/**
 * @file
 * Contains the implementation for the YOUR_MODULE module.
 * Code based on the empty_fields module, but altered to
 * automatically show for every empty field.
 */

use Drupal\Core\Render\Element;

/**
 * Implements hook_entity_display_build_alter().
 */
function YOUR_MODULE_entity_display_build_alter(&$build, $context) {
  /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
  $entity = $context['entity'];
  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
  $display = $context['display'];
  foreach (Element::children($build) as $field_name) {
    if ($entity->get($field_name)->isEmpty()
      && $entity->{$field_name}->access('view')
      && ($formatter = $display->getRenderer($field_name))
    ) {
      $definition = $entity->get($field_name)->getFieldDefinition();
      $component = $display->getComponent($field_name);

      $build[$field_name] = [
          '#theme' => 'field',
          '#title' => $definition->getLabel(),
          '#label_display' => $component['label'],
          '#view_mode' => $context['view_mode'],
          '#language' => $entity->get($field_name)->getLangcode(),
          '#field_name' => $definition->getName(),
          '#field_type' => 'string',
          '#field_translatable' => $definition->isTranslatable(),
          '#entity_type' => $entity->getEntityTypeId(),
          '#bundle' => $entity->bundle(),
          '#object' => $entity,
          '#items' => [(object) ['_attributes' => []]],
          '#is_multiple' => FALSE,
          '#attributes' => ['class' => ['YOUR_MODULE', "YOUR_MODULE__nbsp"]],
          // Use simple formatter.
          '#formatter' => 'string',
          '0' => ['#markup' => '&nbsp;'],
        ] + $build[$field_name];
    }
  }
}
pmagunia’s picture

The solution in #17 seems to work without having to install another module. I added a check to only act on certain fields after the foreach:

if (!($field_name == 'MY_FIELD' || $field_name == 'MY_OTHER_FIELD')) {
  continue;
}