<p>Use two queries: The first to get all products related to the current title, the second one to get all product categories related to any of the products. The query can't return duplicates, so multiple products from the same category won't result in duplicates. It also allows you to sort the categories returned by the query however you want.</p>
<pre class="lang-twig prettyprint-override"><code>{% for entry in cards %}
    {% set relatedProducts = craft.entries()
        .section('products')
        .relatedTo(entry)
    %}
    {% set categoriesForAllRelatedProducts = craft.entries()
        .section('productCategories')
        .relatedTo(relatedProducts)
        .all()
    %}

    &lt;h3&gt;{{ entry.title }}&lt;/h3&gt;
    {{ categoriesForAllRelatedProducts|map(c =&gt; &quot;[#{c.title}]&quot;)|join(' ') }}
{% endfor %}
</code></pre>

CC BY-SA 4.0
2022-10-21T17:01:45.673Z
Thank you SO much, that works perfectly! Took me a little while to wrap my brain around the 'chaining' of the relations, but actually a very clear and clean solution. Even introduced me to a concrete example of a Twig map filter. Cheers!
Jolle
CC BY-SA 4.0
2022-10-21T13:17:19.967Z
2022-10-24T07:24:36.843Z
2022-10-24T07:24:36.843Z
MoritzLost
<p>I am building a shop with book titles, but most for book titles there is not only a book available for purchase, but there could also be a poster of the book, a bookmark and possibly other products, all related to the book title.</p>
<p>I have these three sections:</p>
<ol>
<li>A <em>channel</em> ‘<strong>titles</strong>’ (where meta content regarding each book is kept)</li>
<li>A <em>channel</em> ‘<strong>products</strong>’
 - has a relation field to the book title entry
 - has a relation field to the productCategories entry</li>
<li>A <em>structure</em> ‘<strong>productCategories</strong>’ (with entries ‘book’, ‘poster’, ‘bookmark’ etc)</li>
</ol>
<p>In short: I need to get the productCategories that are related to each book title. If this were a direct relation, this would more or less do:</p>
<pre><code>{% set relatedProductCategories = craft.entries()
      .section('productCategories')
      .relatedTo(entry) %}
</code></pre>
<p>However, the relation between these two goes through the product entry: when creating a new product entry, you select the relations to the book title, and the product category.</p>
<p>On the book titles index/listing page, the book title entries are displayed as cards, with a cover image and the title of the book.
On these cards however, I also want to display what type of products (productCategories) there are for this book title as little labels. So users can see if there is just the book available, or also other products related to this book. A bit like this:</p>
<blockquote>
<p>WAR AND PEACE
[book] [bookmark] [poster]</p>
</blockquote>
<blockquote>
<p>THE LORD OF THE RINGS
[book] [poster] [calendar]</p>
</blockquote>
<p>I can access the product categories with an element query looking for entries in ‘products’ that are (reverse) related to the book title, and then reference the productCategory relation field:</p>
<pre><code>{% set cards = craft.entries()
       .section('titles')
       .limit(null)
       .all() %}

{% for entry in cards %}

     &lt;h3&gt;{{ entry.title }}&lt;/h3&gt;

     {% set relatedProducts = craft.entries
            .section('products')
            .relatedTo(entry) %}

      {% for product in relatedProducts %}
           {{ product.productCategory[0] }}
      {% endfor %}

{% endfor %}
</code></pre>
<p>This works in displaying the productCategories, but when I have multiple products of the same productCategory, they are printed as many times. So on the card, if I would have two posters, it will say:</p>
<blockquote>
<p>WAR AND PEACE
[book] [bookmark] [poster] [poster]</p>
</blockquote>
<p>How do I avoid these duplicates?</p>
<p>Also, the results are displayed in order of product entries, not in order of the productCategories, so it’s currently actually more like this:</p>
<blockquote>
<p>WAR AND PEACE
[poster] [bookmark] [book] [poster]</p>
</blockquote>
<p>How would I order these results in accordance with the structure of the section productCategories?</p>

<relations>
Related entries: prevent duplicate results and order results by structure
# Related entries: prevent duplicate results and order results by structure

(Asked by: username_0 on 2022-10-21)

I am building a shop with book titles, but most for book titles there is not only a book available for purchase, but there could also be a poster of the book, a bookmark and possibly other products, all related to the book title.
I have these three sections:

A channel ‘titles’ (where meta content regarding each book is kept)
A channel ‘products’
 - has a relation field to the book title entry
 - has a relation field to the productCategories entry
A structure ‘productCategories’ (with entries ‘book’, ‘poster’, ‘bookmark’ etc)

In short: I need to get the productCategories that are related to each book title. If this were a direct relation, this would more or less do:
{% set relatedProductCategories = craft.entries()
      .section('productCategories')
      .relatedTo(entry) %}

However, the relation between these two goes through the product entry: when creating a new product entry, you select the relations to the book title, and the product category.
On the book titles index/listing page, the book title entries are displayed as cards, with a cover image and the title of the book.
On these cards however, I also want to display what type of products (productCategories) there are for this book title as little labels. So users can see if there is just the book available, or also other products related to this book. A bit like this:

WAR AND PEACE
[book] [bookmark] [poster]


THE LORD OF THE RINGS
[book] [poster] [calendar]

I can access the product categories with an element query looking for entries in ‘products’ that are (reverse) related to the book title, and then reference the productCategory relation field:
{% set cards = craft.entries()
       .section('titles')
       .limit(null)
       .all() %}

{% for entry in cards %}

     {{ entry.title }}

     {% set relatedProducts = craft.entries
            .section('products')
            .relatedTo(entry) %}

      {% for product in relatedProducts %}
           {{ product.productCategory[0] }}
      {% endfor %}

{% endfor %}

This works in displaying the productCategories, but when I have multiple products of the same productCategory, they are printed as many times. So on the card, if I would have two posters, it will say:

WAR AND PEACE
[book] [bookmark] [poster] [poster]

How do I avoid these duplicates?
Also, the results are displayed in order of product entries, not in order of the productCategories, so it’s currently actually more like this:

WAR AND PEACE
[poster] [bookmark] [book] [poster]

How would I order these results in accordance with the structure of the section productCategories?

**Tags:** relations

---

## 1 answers

### Answer by username_1 on 2022-10-21. Score: 1 | Accepted answer

Use two queries: The first to get all products related to the current title, the second one to get all product categories related to any of the products. The query can't return duplicates, so multiple products from the same category won't result in duplicates. It also allows you to sort the categories returned by the query however you want.
{% for entry in cards %}
    {% set relatedProducts = craft.entries()
        .section('products')
        .relatedTo(entry)
    %}
    {% set categoriesForAllRelatedProducts = craft.entries()
        .section('productCategories')
        .relatedTo(relatedProducts)
        .all()
    %}

    {{ entry.title }}
    {{ categoriesForAllRelatedProducts|map(c => "[#{c.title}]")|join(' ') }}
{% endfor %}

> **Comments:**
> **username_0**: Thank you SO much, that works perfectly! Took me a little while to wrap my brain around the 'chaining' of the relations, but actually a very clear and clean solution. Even introduced me to a concrete example of a Twig map filter. Cheers!  

---

