Simplified Drupal Field Template (but the same markup rendered)

Here's a small edit to the Drupal field template we could make so it's much easier to read.

Simplified version of Drupal field template

Everytime I look at the Drupal field template, I struggle with the conditions nested inside it - if label, if multiple, else not multiple but still label, etc, etc. ... so I thought, "why not make it simpler".

Here's the original field template:

{% if label_hidden %}
  {% if multiple %}
    <div{{ attributes.addClass(classes, 'field__items') }}>
      {% for item in items %}
        <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
      {% endfor %}
    </div>
  {% else %}
    {% for item in items %}
      <div{{ attributes.addClass(classes, 'field__item') }}>{{ item.content }}</div>
    {% endfor %}
  {% endif %}
{% else %}
  <div{{ attributes.addClass(classes) }}>
    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
    {% if multiple %}
      <div class="field__items">
    {% endif %}
    {% for item in items %}
      <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
    {% endfor %}
    {% if multiple %}
      </div>
    {% endif %}
  </div>
{% endif %}

and here is my updated version which will render the same markup for us:

<div{{ attributes.addClass(classes) }}>
  {% if not label_hidden %}
    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
  {% endif %}
  <div class="field__items">
    {% for item in items %}
      <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
    {% endfor %}
  </div>
</div>

What's the difference? In mine, we do an explicit check for a field label and either render it or not. Following that, we render the field items, without checking if they are "multiple" or not. Now, this does cause a small difference with the original template - it means we always render a container div with a class of ".field__items". However, I see this as a feature. It means we get the exact same markup on single fields as we get on fields with multiple items.

Why is this a feature? Well, it means when writing our CSS and we want to target the immediate ".field__item", we don't have to do something like this:

/* If multiple */
.field--news-authors > .field__items > .field__item  {
  color: red;
}

/* If only one item */
.field--news-authors > .field__item {
  color: red;
}

Enforcing a consistency in our classes and having a much easier to read template is good.

Filed Under:

  1. Drupal Planet
  2. Drupal
  3. HTML
  4. Twig