Having a field output custom markup when empty So due to very rare use-case client issues, we've had to use a somewhat hacky solution to solve one of our goals. I am looking for a solution (hacky is fine) to solve one of the problems created by this solution. This is in Drupal 8 for reference.

I'll give the breakdown of where we are, and what sort of solution we're trying to achieve:

We needed to essentially duplicate the functionality of the menu system based on dynamic values on a given page, based on relevant field values. Occasionally, this would have to be done several times over.

To do this, we used a module that allowed us to place HTML elements inside the node display to wrapper several fields that would all be displayed inside this "menu", so that they'd have the proper menu markup.

We also created a custom display suite template to display each row properly (i.e. it contains the menu markup for each row) and we're using that as the field widget for each given field.

So it looks like this in the Manage Display page:

div
    ul
         FIELD (with the custom DS template widget)


Here's the problem:

We also need to have a couple of static links, based on the URL with some arbitrary additional pathing afterwards, which we're currently doing in the custom template (unfortunately with logic in the template).

Looks like this:

{% if element['#field_name'] == 'field_name_1' or element['#field_name'] == 'field_name_2' %}
    &lt;li class="menu-item {{ element['#field_name'] }}" data-responsive-menu="accordion large-dropdown"&gt;&lt;a href="{{ url('&lt;current&gt;') }}/url1" &gt;Link1&lt;/a&gt;&lt;/li&gt;
    &lt;li class="menu-item {{ element['#field_name'] }}" data-responsive-menu="accordion large-dropdown"&gt;&lt;a href="{{ url('&lt;current&gt;') }}/url2" &gt;Link2&lt;/a&gt;&lt;/li&gt;
    {%endif %}


The only problem is that since this requires a given field to have a value in it, and the links always need to be rendered, we want to know if there's a way to insert a value so that a specific field is never truly empty.

We were thinking of putting in &amp;NoBreak; for markup. How would we go about checking if a field is empty, and if so, inserting custom markup into it so that the template always renders the field?

We tried HOOK_node_view_alter(), but that gives us a render array that isn't particularly easy to traverse or modify (though maybe this is the solution, I'm not sure). We've tried putting in a 

$build['#post_render'][] = 'MY_MODULE_node_post_render';


hook, but that seems to give us the HTML in a way that isn't easily changeable.

So the question is - how do we put custom markup in an empty field to be displayed in a given entity view mode, but display the normal results of the field if there are results?
This is what I eventually did to get it to work.

function MY_MODULE_entity_display_build_alter(&amp;$build, $context) {
  $view_mode = $context['view_mode'];
  $object = $context['entity'];
  if (empty($build['field_machine_name']['#field_type'])) {
    $field = 'field_machine_name';
    $build['field_machine_name'] = global_events_faux_element($build, $field, $view_mode, $object);
  }
}

function MY_MODULE_faux_element($build, $field, $view_mode, $object) {
  $element = array(
    '#theme' =&gt; "field",
    '#title' =&gt; "Field Name Here",
    '#label_display' =&gt; "hidden",
    '#view_mode' =&gt; $view_mode,
    '#language' =&gt; "en",
    '#field_name' =&gt; $field,
    '#field_type' =&gt; "text_long",
    '#field_translatable' =&gt; FALSE,
    '#entity_type' =&gt; "node",
    '#bundle' =&gt; "bundle_name",
    '#formatter' =&gt; "smart_trim",
    '#is_multiple' =&gt; FALSE,
    '#object' =&gt; $object,
    '0' =&gt; array(
      '#markup' =&gt; "&amp;NoBreak;",
    ),
    '#weight' =&gt; 2,
  );
  return $element;
}