1

I have a matrix field that includes a tags field. The matrix includes a list of events, with each event using the tag field to determine topics. I'd like to output a list of each tag used, so I can filter the events by those tags. When I try to output the tags, I get every instance of the tag being used, rather than just a list of each unique tag. Where am I going wrong?

{% for block in entry.events %}
    {% for tag in block.topics %}
            {{ tag.title }}
    {% endfor %}
{% endfor %}

1 Answer 1

2

You're manually iterating through all matrix blocks, then you iterate again through all tags in that block. So if multiple blocks include the same tag, of course you're going to see the tag multiple times.

To fix this, instead of manually looping through the matrix blocks, use a single tag query to find all tags that are related to any of the matrix blocks on the current entry:

{% set matrixBlocks = entry.events.ids() %}

{% set tagsInMatrixBlocks = craft.tags()
    .group('topics')
    .relatedTo({
        field: 'topics',
        sourceElement: matrixBlocks,
    })
    .orderBy('title ASC')
    .all()
%}

Because this is a single query, you avoid duplicates. As a nice benefit, you can also sort the query however you'd like, in this case alphabetically. Note the use of ids() instead of all(). We don't need the full matrix blocks in this case, so we only retrieve a list of IDs from the database to improve performance. Then we use relatedTo to find all tags in the topics group (replace with the handle of your tags group) that are related to any of those matrix blocks; the specific form of the relatedTo parameter further limits the query to relations in the topics field where the matrix block is the source element, i.e. the element where the related tags are selected. See the documentation on relations for more details and examples.

The tag query returns an array of Tag objects, you can iterate through the array and access all properties and custom fields on it:

{% for tag in tagsInMatrixBlocks %}
    {{ tag.title }}
{% endfor %}
2
  • Thank you! That all makes sense. Then how do I output that? Should it be: {% for tag in tagsInMatrixBlocks %}{{ tag.title }}{% endfor %} ?
    – univers0
    Commented Apr 3, 2023 at 19:52
  • @univers0 Yes, that's right. I've added a code example to my answer.
    – MoritzLost
    Commented Apr 4, 2023 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.