<p>I think you're nearly there! Give this a shot:</p>

<pre><code>{% set allEntriesByPrename = allEntries | group('{{ (object.composerName | first).lastName | upper | slice(0, 1) }}') %}
</code></pre>

<p>I believe the issue is that relations always come back as an <em>array</em>, and you were trying to immediately access a property of the <code>Element</code> at index <code>0</code> in that array, rather than de-referencing it, <em>then</em> accessing the property.</p>

<p>Be aware that this may generate some deprecation errors, as using the <code>first</code> filter will attempt to use the relational field as an array. Instead, I'd recommend eager-loading your Composers along with the Compositions--in addition to being safer, moving forward, it avoids an N+1 problem, and will <em>dramatically</em> reduce the number of queries on your page:</p>

<pre><code>{# See: `with`, including the `composerName` field handle: #}
{% set allEntries = craft.entries({
  section: 'komposition',
  limit: null,
  with: [
    ['composerName']
  ]
}).all()

{# Grouping by a relation will no longer trigger another query per Composition: #}
{% set allEntriesByPrename = allEntries | group('{{ (object.composerName | first).lastName | upper | slice(0, 1) }}') %}
</code></pre>

<blockquote>
  <p><strong>Note:</strong> I had to use the expanded syntax for the <code>group</code> filter (<code>{{ ... }}</code>) in order to enforce the proper order of operations. In that context, <code>object</code> is a reference to the Composition.</p>
</blockquote>

CC BY-SA 4.0
2020-01-10T11:47:49.317Z
If I wrap the group filter into `{{}}` I get  `A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "}" ("punctuation" expected with value ":")`
KSPR
CC BY-SA 4.0
2020-01-10T12:08:16.247Z
Is it still surrounded with single quotes, or did you remove those in the process?
August Miller
CC BY-SA 4.0
2020-01-10T12:10:12.957Z
yes is use single quotes: `{% set allEntriesByPrename = allEntries | group('{{object.composerName | first .lastName|upper|slice(0, 1)}}') %}`
KSPR
CC BY-SA 4.0
2020-01-10T12:12:25.683Z
Same like this: `{% set allEntriesByPrename = allEntries | group('{{ (object.komponistRelated | first).nachname | upper | slice(0, 1) }}') %}`
KSPR
CC BY-SA 4.0
2020-01-05T20:03:47.343Z
2020-01-05T20:03:47.343Z
August Miller
<p>A little late to the party here, but in case anyone else comes across this post.</p>
<p>The suggestion that August was making <a href="https://craftcms.stackexchange.com/a/33348/10878">here</a> was very close, but when I tried something similar, I was running into the same error as @KSPR</p>
<p><code>A hash key must be followed by a colon (:). Unexpected token &quot;punctuation&quot; of value &quot;}&quot; (&quot;punctuation&quot; expected with value &quot;:&quot;)</code></p>
<p>According to the docs for Crafts <a href="https://craftcms.com/docs/3.x/dev/filters.html#group" rel="nofollow noreferrer">twig group filter</a> what you actually need is something like this:</p>
<pre><code>{% set allEntriesByPrename = allEntries | group( e =&gt; (e.composerName| first).lastName | upper | slice(0, 1) ) %}
</code></pre>

CC BY-SA 4.0
2023-01-29T09:14:49.633Z
2023-01-29T09:14:49.633Z
stevecomrie
<p>I have a channel of Musical Compositions:</p>

<p><a href="https://i.sstatic.net/UTAtB.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/UTAtB.png" alt="enter image description here"></a></p>

<p>Now all these Compositions have a Composer.
All the composers are stored in a separate channel and then linked with their respective compositions trough a <a href="https://docs.craftcms.com/v3/entries-fields.html" rel="nofollow noreferrer">entries field</a></p>

<p>Now I like to order the compositions by the last name of the composer and group them together alphabetically.</p>

<p>I managed them to be grouped but not by the composer name, just by the composition title which is not helpful.</p>

<pre><code>{% set allEntries = craft.entries.section('komposition').limit(null) %}
{% set allEntriesByPrename = allEntries | group('title|upper|slice(0, 1)') %}

{% for letter, allEntriesSorted in allEntriesByPrename %} 
 {# stuff #}
{% endfor %}
</code></pre>

<p>Now the catch here is the group filter I guess but when I use the handle of the entries field it doesn't work:</p>

<pre><code>| group('composerRelated.lastName|upper|slice(0, 1)')
</code></pre>

<p>If I write it like this, the group filter simply is ignored. Since the entries field returns an array I have no idea how to write this. And I think at the time of the group filter the entries field is not available yet.</p>

<p>I also tried to grab all composers from the section and put it into the group filter:</p>

<pre><code>{% set allEntries = craft.entries.section('komposition').limit(null) %}
{% set composerName = craft.entries.section('komponist').limit(null) %}

{% set allEntriesByPrename = allEntries | group('composerName.lastName|upper|slice(0, 1)') %} 
</code></pre>

<p>This is too much inception for me. How do I have to write this?</p>

<templating><craft3><entries-field><group>
Group by related entries field
# Group by related entries field

(Asked by: username_0 on 2020-01-05)

I have a channel of Musical Compositions:

Now all these Compositions have a Composer.
All the composers are stored in a separate channel and then linked with their respective compositions trough a entries field
Now I like to order the compositions by the last name of the composer and group them together alphabetically.
I managed them to be grouped but not by the composer name, just by the composition title which is not helpful.
{% set allEntries = craft.entries.section('komposition').limit(null) %}
{% set allEntriesByPrename = allEntries | group('title|upper|slice(0, 1)') %}

{% for letter, allEntriesSorted in allEntriesByPrename %} 
 {# stuff #}
{% endfor %}

Now the catch here is the group filter I guess but when I use the handle of the entries field it doesn't work:
| group('composerRelated.lastName|upper|slice(0, 1)')

If I write it like this, the group filter simply is ignored. Since the entries field returns an array I have no idea how to write this. And I think at the time of the group filter the entries field is not available yet.
I also tried to grab all composers from the section and put it into the group filter:
{% set allEntries = craft.entries.section('komposition').limit(null) %}
{% set composerName = craft.entries.section('komponist').limit(null) %}

{% set allEntriesByPrename = allEntries | group('composerName.lastName|upper|slice(0, 1)') %} 

This is too much inception for me. How do I have to write this?

**Tags:** templating, craft3, entries-field, group

---

## 2 answers

### Answer by username_1 on 2020-01-05. Score: 1 | Accepted answer

I think you're nearly there! Give this a shot:
{% set allEntriesByPrename = allEntries | group('{{ (object.composerName | first).lastName | upper | slice(0, 1) }}') %}

I believe the issue is that relations always come back as an array, and you were trying to immediately access a property of the Element at index 0 in that array, rather than de-referencing it, then accessing the property.
Be aware that this may generate some deprecation errors, as using the first filter will attempt to use the relational field as an array. Instead, I'd recommend eager-loading your Composers along with the Compositions--in addition to being safer, moving forward, it avoids an N+1 problem, and will dramatically reduce the number of queries on your page:
{# See: `with`, including the `composerName` field handle: #}
{% set allEntries = craft.entries({
  section: 'komposition',
  limit: null,
  with: [
    ['composerName']
  ]
}).all()

{# Grouping by a relation will no longer trigger another query per Composition: #}
{% set allEntriesByPrename = allEntries | group('{{ (object.composerName | first).lastName | upper | slice(0, 1) }}') %}


Note: I had to use the expanded syntax for the group filter ({{ ... }}) in order to enforce the proper order of operations. In that context, object is a reference to the Composition.

> **Comments:**
> **username_0**: If I wrap the group filter into `{{}}` I get  `A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "}" ("punctuation" expected with value ":")`  
> **username_1**: Is it still surrounded with single quotes, or did you remove those in the process?  
> **username_0**: yes is use single quotes: `{% set allEntriesByPrename = allEntries | group('{{object.composerName | first .lastName|upper|slice(0, 1)}}') %}`  
> **username_0**: Same like this: `{% set allEntriesByPrename = allEntries | group('{{ (object.komponistRelated | first).nachname | upper | slice(0, 1) }}') %}`  

---

### Answer by username_2 on 2023-01-29. Score: 2

A little late to the party here, but in case anyone else comes across this post.
The suggestion that August was making here was very close, but when I tried something similar, I was running into the same error as @KSPR
A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "}" ("punctuation" expected with value ":")
According to the docs for Crafts twig group filter what you actually need is something like this:
{% set allEntriesByPrename = allEntries | group( e => (e.composerName| first).lastName | upper | slice(0, 1) ) %}


---

