1

I'm trying to loop through a Super Table array and group results based on a category ('contribution'). I've gotten pretty far but I'm struggling creating an array in Twig that gives me what I need (I find associative arrays very cumbersome in Twig after using PHP for so long...).

Setting the contribution works. I just can't seem to write the merge rule correctly so each contributor merges into their respective role. The next step would to then join together the list of names for further output...

Here is where I am currently stuck:

  {% set featuredContributors = [] %}

  {% for person in book.contributors.all() %}
    {% if person.featured == 1 %}
      {% set contribution = person.contribution.one().title %}
      {% set contributor = person.contributor.one().title %}
      {% set featuredContributors =
        featuredContributors |
          merge({
          (contribution): [contributor]
          })
      %}
    {% endif %}
  {% endfor %}

The resulting array should look like (with each array joined as a comma separated list):

{% set featuredContributors = {
  Editor: 'Person One, Person Two',
  Writer: 'Person Three, Person Four',    
  Other Role: 'Person Five',    
} %}

Is there an easier way to do this? PHP via a Twig Extension? :D

1

For grouping arrays, use Craft's group filter or index filter, then for joining the array items with commas use Twig's join filter.

Something like this might be what you're looking for (I've also added eager loading for improved performance, and I used the map filter as a cleaner way of organising the array, though you could use a nested loop if you find it easier to read):

{% set featuredPeopleGrouped = book.contributors
    .featured(1)
    .with(['contribution','contributor'])
    .all()|group('contribution[0]')
%}

<dl>
    {% for contributionType, rowData in featuredPeopleGrouped %}
        {% set contributors = rowData|map(row => row.contributor[0].title) %}
        <dt>{{ contributionType }}: </dt>
        <dd>{{ contributors|join(', ') }}</dd>
    {% endfor %}
</dl>
2
  • Epic -- Thank you so much for the hint about the Map filter and tip about Eager Loading. Much appreciated. – Document Services Sep 20 '20 at 21:36
  • @DocumentServices My pleasure, if you could mark the answer as accepted that would be appreciated :-) – James Smith Sep 21 '20 at 6:52

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.