You can access single value field in node template easily:

{{ content.field_test }}
or
{{ node.field_test.value }}

But iteration over multiple value fields is not pretty:

{% for key, item in content.field_tags if key|first != '#' %}
  <div class="item-{{ key + 1 }}">{{ item }}</div>
{% endfor %}

You can, of course, use a field template, but sometimes it doesn't make sense to have a ton of field template when you can simply have one node template.

Example:

I need to add "," between a field's values (a multiple value entity references field rendered in label). So I have a field template with:

{% for item in items %}
  {{ item.content }}{% if not loop.last %},{% endif %}
{% endfor %}

And in my node template I have:

{% if content.field_facilities is not empty %}
   <p>{{ content.field_facilities }}</p>
{% endif %}

But I would prefer to have a similar code directly in my node template like:

{% if content.field_facilities is not empty %}
   <p>
     {# This do not works! #}
     {% for item in content.field_facilities %}
       {{ item.content }}{% if not loop.last %},{% endif %}
     {% endfor %}
   </p>
{% endif %}

What would be the best way to solve that?

See also:

Comments

gagarine created an issue. See original summary.

gagarine’s picture

Issue summary: View changes
gagarine’s picture

Issue summary: View changes
gagarine’s picture

Issue summary: View changes
gagarine’s picture

The problem is mainly with entity reference.

One solution would be to create a twig filter passing the value to Element::children

That will then be somethings like

{% for item in content.field_tags|children %}
  <p>{{ item }}</p>
{% endfor %}

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mezitlab’s picture

Regarding Gagarin's answer, here is the code of the Twig filter that I simply put in a custom module.

mymodule/mymodule.services.yml

services:
  mymodule.twig_extension:
    arguments: ['@renderer']
    class: Drupal\mymodule\TwigExtension\Children
    tags:
      - { name: twig.extension }

mymodule/src/TwigExtension/Children.php

namespace Drupal\mymodule\TwigExtension;


class Children extends \Twig_Extension
{

  /**
   * Generates a list of all Twig filters that this extension defines.
   */
  public function getFilters()
  {
    return [
      new \Twig_SimpleFilter('children', array($this, 'children')),
    ];
  }


  /**
   * Gets a unique identifier for this Twig extension.
   */
  public function getName()
  {
    return 'mymodule.twig_extension';
  }


  /**
   * Get the children of a field (FieldItemList)
   */
  public static function Children($variable)
  {
    if (!empty($variable['#items'])
      && $variable['#items']->count() > 0
    ) {
      return $variable['#items']->getIterator();
    }

    return null;
  }

}

in the Twig template (it will result a plain-text output):

  {% for item in content.field_tags|children %}
    {{ item.get('value').getValue() }}
  {% endfor %}

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

webcultist’s picture

As a front guy I can say, I already needed and still need this! Don't know how much time I already wasted on workarounds...

dawehner’s picture

As a first step it would be nice to add this to https://www.drupal.org/project/twig_extensions or https://www.drupal.org/project/twig_tweak
Allowing people to have access to it as soon is possible is a nice feature.

Anybody’s picture

Yes this would be very useful in core or first in one of these helper modules. We're having that problems with paragraphs... ugly workaround.

mini.addweb’s picture

We can find the solution to this problem by different types of approaches:

1. I am explaining this an example. Like if we are having an array named testArray from the controller to a twig template and want to print every element.

{% for element in testArray %}
        {{ element.someString }}, 
    {% endfor %} 

    <!--  output: 'test1, test2, test3, ' -->

2.

{{ myArray|join(', ') }}

    <!--  output: 'test1, test2, test3, ' -->

3. Another option to do it by this code

    {% for role in user.roles %}
        {{ role.name }}
        {% if not loop.last %},{% endif %}
    {% endfor %}

Hope this helps you.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.