Drupal - How to tell if a field has renderable content before printing HTML around it?
The answers so far are only valid for non reference fields. A reference field is different, because the referenced entities can have different access results than the parent entity. The rendered field can be empty although the field in the node object is not. As explained in How do I hide an empty field if my custom field formatter removes all items? there are two unambiguous empty conditions for the output of the field formatter in {{ content.field_name }}
:
Check the first field delta, which always starts with
0
:{% set display_related = content.field_name.0 is defined %}
or check whether the field formatter could find any renderable children and has added the field wrapper:
{% set display_related = content.field_name['#theme'] is defined %}
For a reference field it is important to render content.field_name
even if the result is negative, because it contains the cacheable metadata of the access checks. When for example a referenced node is published, the parent node needs to be invalidated and rerendered.
So checking content.field_name|render|striptags|trim
is not so bad at all, because this check renders the field content and if the result is negative you don't have to render the field again, because the metadata bubbled up already.
Field Groups
For halve a dozen fields you could use Field Groups. Place all reference fields in a group "Related" and display the header in the field group template. If the field group template doesn't hide automatically you can check with striptags
as before. You get the entire rendered result of all fields in the variable children
.
Although I would prefer to check the specific content you expect to be inside of the field group and so ignore labels or other things that may be added later. The already rendered field group content is in a markup object and you need to render it again in twig, so you can check it casted as a string. For example whether it contains a linked node:
field-group-html-element.html.twig:
{% set display_related = '<a href' in children|render %}