Hi,

not sure if this should be a bug report but let's start with a support request :)

Currently, we have to use the following code for conditionals based fields:

{% if content.field_more_infos['#items'] is not empty %}
  <div class="my-field-wrapper">
    {{ content.field_more_infos }}
  </div>
{% endif %}

would be much nicer if this worked intuitively:

{% if content.field_more_infos %}
  <div class="my-field-wrapper">
    {{ content.field_more_infos }}
  </div>
{% endif %}

Comments

dasjo created an issue. See original summary.

dasjo’s picture

When we figure out the proper way to handle this, let's add it to the docs:
https://www.drupal.org/node/1918824

star-szr’s picture

joelpittet’s picture

Status: Active » Closed (duplicate)

I think @Cottser is correct.

Try this.

{% if content.field_more_infos|render %}
  <div class="my-field-wrapper">
    {{ content.field_more_infos }}
  </div>
{% endif %}

Or

{% set more_infos =  content.field_more_infos|render %}
{% if more_infos %}
  <div class="my-field-wrapper">
    {{ more_infos }}
  </div>
{% endif %}
joelpittet’s picture

Also there is no really good way to deal with this problem at the moment in Twig or PHP template because it's hard to know what makes a render array truely empty and performance implications. Please continue the discussion in that issue referenced in #3

jwilson3’s picture

I'm finding that |render is not enough due to random whitespace issues from field templates, but the following works:

{% if content.field_more_infos|render|trim is not empty %}
  
    {{ content.field_more_infos }}
  
{% endif %}

the "is not empty" part may not be necessary, but |render|trim is absolutely needed.

chi’s picture

@jwilson3 here is the trick for views. I suppose it works for fields as well.
https://www.drupal.org/node/2783633#comment-11510195

hkirsman’s picture

Tx, works for me at the moment in ds-2col-stacked.html.twig:

{%  if left|render|trim %}
    <{{ left_wrapper }}{{ left_attributes.addClass('group-left') }}>
      {{ left }}
    </{{ left_wrapper }}>
  {% endif %}
autopoietic’s picture

In case it helps someone else, I found that {% if content.field_myfield|render|trim is not empty %} does not work as expected if twig debug is enabled, because template suggestions are still returned when the field is otherwise empty.

natemow’s picture

Use "striptags" to remove Twig debug comments: {% if content.field_myfield|render|striptags|trim is not empty %}

ArchieV’s picture

Using "|render", "|strip_tags" is only good if you have your output properly cached, and it still might not cover all edge cases.

From what I can see here - it's a entity template.
In this case you can get values directly from entity (which in most cases available in template). So if you need to print, let's say, field_date on your node page, you can do something like:

{% if node.field_date.value %}
  <div class="my-field-wrapper">
    {{ content.field_date }}
  </div>
{% endif %}
hmartens’s picture

Thank you so much for your input ArchieV! This worked for me. I used {% if my_paragraph_field.value %} and that worked perfect for me!

This works so much better than guessing what you should keep adding like |strip_tags|tags|sotiredofguessingthetagthatwillwork

hmartens’s picture

I see that in one twig I just have to use {% if not banner_image %} and on another twig file it doesn't work...is it just me or is it flaky?

Some settings on the images.

rominronin’s picture

In response to #11, the .value suffix may work if you have access to node, this is not always the case (this returns NULL on a display suite template, where I'm having difficulty checking for empty regions).

I didn't want to sound negative when I hit the comment button, but now that I think about it; the benefits offered by twig that attracted the Drupal decision makers to it are not so easy to pass on to an important group of Drupal users: themers, newcomers, template builders.

It's great that there is a workaround like 'node.field.value' for *some* use cases, but then we need to have Drupal specific documentation for twig. I'm happy with the compromises since I know Drupal well enough to know several other ways to get the markup I need, but a newcomer has maybe no hope without a holding hand.

ArchieV’s picture

To #14.

No, it's not *some* use cases and it's not a "workaround". Doing "render|striptags|trim" - is workaround.

This works when you use native templates for most of entities: users, nodes, paragraphs, etc. which is pretty common task and building castles with twig filters is not a good idea when you can do same stuff much in more obvious and bulletproof maner.

"Drupal specific documentation for twig" - link, you are welcome. Drupal already expands twig a lot, so you cannot avoid learning "drupal specific" twig.

"Newcomer has maybe no hope without a holding hand" - we all sitting here to help newcomers to do stuff in best, the most efficient way possible. Answering questions right with covering all possible ways is one of the ways to do that.

rp7’s picture

The solution in #11 did not work for all fields for me - I had to adjust it a little bit to this:

{% if node.field_date[0].value %}
  <div class="my-field-wrapper">
    {{ content.field_date }}
  </div>
{% endif %}
gagarine’s picture

This bug was closed in favor of #953034: [meta] Themes improperly check renderable arrays when determining visibility

If you think this is another bug please reopen. If not, please do not add comment on this one and prefer the other (open) bug.

anonym-developer’s picture

#16 the value ist not necessary. this should be enough:

{% if node.field_date[0] %}
...
{% endif %}
RAWDESK’s picture

#8 worked for me on optional entity referenced fields, like a webform.

artematem’s picture

Be careful with #8. In case you have a webform (with inline confirmation type) in content, it will be submitted twice every time.

RAWDESK’s picture

@artemetem, thanks for the advice

artematem’s picture

Used next workaround for a webform (with inline confirmation type):

{% set left_content = left|render %}
{% if left_content is not empty %}
  {{ left_content }}
{% endif %}
jedgar1mx’s picture

#6 worked great for me

imperator_99’s picture

@ArchieV your solution also worked for me in a View. Thanks very much!

yaronmiro’s picture

Hi you can use a built in method that exists on any field, e.g.

   {% if node.my_field.isEmpty() != true %}
      <div class="some-class">
        {{ node.my_field.value }}
     </div>
   {% endif %}
lauris.kuznecovs@wunder.io’s picture

This helped in my case

{% if content.field_name|render is not empty %}
    <div>{{ content.field_name }} Whatever</div>
{% endif %}
artematem’s picture

@lauris.kuznecovs and if you have a webform in that field you'll have next error https://www.drupal.org/project/webform/issues/2929250#comment-12501991

elaman’s picture

#25 works fine. You can also use it this way:

   {% if not node.my_field.isEmpty() %}
      <div class="some-class">
        {{ node.my_field.value }}
     </div>
   {% endif %}
Andre-B’s picture

RE #26
that will duplicate the rendering of that field. you don't want to do that, it will decrease your overall performance. if you have to check for empty at least store the rendered result away and reuse it like

{%- set content_field_name -%}
  {{ content.field_name }}
{% endset %}

{% if content_field_name is not empty %}
    <div>{{ content_field_name }} Whatever</div>
{% endif %}
prasannag’s picture

Here is another simple approach where the field value can be checked with the existing function getValue().

{% if content.field_name['#items'].getValue() %}
  {{ content.field_name }}
{% endif %}
hmartens’s picture

We work with components which does not have access to the actual Drupal field name aka node.image . Our use-case is that we have a paragraph twig file and then we call a component to render this.

We find it fairly easy to check if a field has content in, but what we used to mostly struggle with is to check if an image is empty. What seems to work fairly well for this is to use the following statement in the component:

{% if image|render is not empty %}
     {{ image }}
{% endif %}

I hope this helps someone.

Andre-B’s picture

RE #31 see #29 same issue - leading to duplicate rendering and bad overall performance.

MoCart’s picture

#30 works for me.

maskedjellybean’s picture

I have to say it's annoying that this hasn't been resolved yet.

The only thing that seems to work consistently for all types of fields is this, but as Andre-B has pointed out, it is bad for performance to render a field twice just to check if it is empty.

{% if image|render is not empty %}
     {{ image }}
{% endif %}

Anyways, for whoever it helps, this seems to work for entity reference fields:

{% if content.field_author['#items'].getValue() %}
    {{ content.field__author }}
{% endif %}

Someday I would like to spend the time to make a list of the various field types and the best way to check whether they are empty so I can stop Googling this thread every few months.

Andre-B’s picture

@maskedjellybean you can store the rendered value in a variable, use that variable for your check and output it in case it's not empty. That removes the duplication of rendering at least - doesn't cover rendering empty things in the first place though, not sure how much performance overhead that is at the end of the day. At least by the store rendered result in variable pattern we could improve render performance dramatically. It's somewhat ugly works in most cases

hudri’s picture

My most bullet-proof solution

{% if not (node.field_whatever.isEmpty == true) and content.field_whatever is defined %}
  <div class="whatever_markup">
    {{ content.field_whatever }}
  </div>
{% endif %}

This solution is the only one working in reusealbe and/or shared templates (e.g. a shared node--teaser.html.twig accross multiple bundles) because

- it works for all field types
- it checks if the field exists
- it checks if the field is not empty
- it checks if the field is not hidden in display mode

The double negative not ...isEmpty == true is necessary, otherwise a non-existing field would fail the check. I also believe that my solution is much faster and resilient to errors than any check that involves rendering the field.

Rant

This is a quite annoying topic in my every day work as a frontend dev. My code above is quite reliable, but becomes unreadable quickly when you have to check for multiple fields. We really need a simple solution for this combined check in core (positive logic!), something like {% if content.field_whatever.hasContent %}

sannminwin’s picture

I used this

{% if not content.field_speaker.value %}

Speakers information will be available soon ...

{% endif %}

Denis Waßmann’s picture

#30 works...

shamsher_alam’s picture

#30 worked for me. Great thanks

navid045’s picture

#31 worked for me. It is simple and logical.

manuel.adan’s picture

#31 works, but the element rendering process is called twice. Cache mitigates it. Another option could be assign the rendered output to a temporary variable, despite it uglifies the code:

{% set image_render = image|render %}
{% if image_render is not empty %}
     {{ image_render }}
{% endif %}
robert_t_taylor’s picture

After much consternation and trying a whole slew of suggestions, #36 finally worked for me. Thanks, hudri!

wxman’s picture

Just adding my two cents. After a lot of testing, #36 was the only one that worked for me too.

gaspounet’s picture

In my case, it's working this way:

{% if content.some_field | render | join | striptags | trim %}
  {{ content.some_field }}
{% endif %}
Andre-B’s picture

#44 leads to duplication of rendering as well. this is a huge performance problem since if you're rendering an entityreference field that might include another bunch of other templates with a similar / same approach you're suddenly rendering a lot more templates than just one or two. I've seen this in production and fixing all the cases in the template took time.

Do not use this pattern of if render check, render again!

{% if content.some_field | render %}
  {{ content.some_field }}
{% endif %}

If you absolutely have to to something like

{%- set content_field_name -%}
  {{ content.field_name }}
{% endset %}

{% if content_field_name is not empty %}
    <div>{{ content_field_name }} Whatever</div>
{% endif %}

(as already mentioned in #26 and #41)

Anonymous’s picture

I think this solution by Hudri is a good way to check if a field is empty: https://drupal.stackexchange.com/a/277157/61171

{% if not (node.field_whatever.isEmpty == true) and content.field_whatever is defined %}
  <div class="whatever_markup">
    {{ content.field_whatever }}
  </div>
{% endif %}

Check the original comment for further info.

This worked for me when everything else did not.

maskedjellybean’s picture

I've been documenting the Twig code I've used in a recent project for checking and accessing field values. I suspected that maybe the way we need to check varies depending on field type and formatter. So far I haven't found that. In fact {% if content.field_name.0 %} has worked for me to check if not empty in all cases except a boolean field. I can't confidently say any of this will work for your situation, but just in case it helps someone: https://docs.google.com/spreadsheets/d/1NjRA8DzXnlBPuSLgivE4-8HJMgu33Ldd...

alexborsody’s picture

Sad that have to resort to #35 in a preprocess function to get this done.

khaled_webdev’s picture

Is the bundle class a better solution by creating a function like hasSomeField()?

markconroy’s picture

I use {% if node.field_example.value %} and have been very happy with it.

Same with {% if paragraph.field_example.value %} and {% if media.field_example.value %} etc