1

In a Twig template, I'm conditionally rendering a sidebar based on whether custom field content.field_body (Paragraphs entity reference revisions field type) contains any items.

{% if content.field_body['#items'] %}
  <div class="jump-sidebar mb-5">
    <h3 class="text-sans">In this article:</h3>
    <ul class="list-unstyled">
      {% for item in content.field_body['#items'] %}
        {% if item.entity.field_subhead %}
          <li class="text-18">
            <a href="#{{ item.entity.field_subhead.value | clean_class | trim }}">{{ item.entity.field_subhead.value | raw }}</a>
          </li>
        {% endif %}
      {% endfor %}
    </ul>
  </div>
{% endif %}

This worked fine until the requirements changed. :)

Now I need to render this entire sidebar <div> if and only if one of the item.entity.field_subhead fields in the ['#items'] array contains a value.

{{ dump(content.field_body['#items']|keys) }} returns the following:

^ array:2 [▼
  0 => 0
  1 => 1
]

So the ['#items'] are a regular numerically-indexed array.

Rephrasing the question, is it possible in Twig to write a conditional that returns true if any key of a multi-value field contains a specific field?

This is further complicated by the fact that there may be different Paragraph types referenced here, and only one of these (the "Section" paragraphs type) will contain entity.field_subhead, but there might be any number of Sections.

Bonus points if whitespace returns false.

EDIT: Thanks @Hudri!

For future reference, the code that worked in my case looked like this:

{# Test every Section for non-empty Subhead #}
{% set render_sidebar = false %}
{% for field_item in node.field_body %}
  {% if field_item.entity.field_subhead %}
    {% if not field_item.entity.field_subhead.isEmpty %}
      {% set render_sidebar = true %}
    {% endif %}
  {% endif %}
{% endfor %}
{# If any Section contains non-empty Subhead, render block #}
{% if render_sidebar %}
  <div class="jump-sidebar mb-5">
    {# a bunch of markup #}
  </div>
{% endif %}
2

I'd always do data checks on the entity object (in this case node), and not on the render array content. The second part is the magic .entity to get the linked referenced entity from the host's entity reference field:

{% set render_something = false %}
{% for field_item in node.field_entity_reference %}
  {% if not field_item.entity.field_to_check.isEmpty %}
    {% set render_something = true %}
  {% endif %}
{% endfor %}

{% if render_something %}
  <div class="my_wrapper">
    ...content...
  </div>
{% endif %}

Be warned though data behind .entity is usually not cache-safe (but it is cache-safe in this special case with Paragraphs, because their revisioning is directly tied to their host entity)

-2

So I had this similar issue and decided it was much easier to do this in a preprocess function rather than trying to handle it in twig, and then pass has_sidebar as a variable to the template. Much easier to handle this in something like preprocess_node or something like that. Our case was a little more complex because it had to be pre content type, but that premise was the same. This is the case where preprocess is really the best option.

2

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.