1

I would like group entries first by what category they are in, than group by month based on a Date/Time field like this for example:

  • Category 1
    • February 2017
      • Event 1
    • March 2017
      • Event 4 (in all categories)
  • Category 2
    • February 2017
      • Event 2
      • Event 5
    • March 2017
      • Event 4 (in all categories)
  • Category 3
    • March 2017
      • Event 4 (in all categories)

Here is what I'm currently using:

{% set eventCategories = craft.categories.group('events').find() %}
{% set eventEntries = craft.entries.section('event').order('dayStart asc').limit(null) %}
{% for category in eventCategories %}
    <h1>{{ category.title }}</h1>
        {% for eventDate, entries in eventEntries | group("dayStart|date('F Y')") %}
            <h2>{{ eventDate }}</h2>
            <ul>
                {% for entry in eventEntries.relatedTo(category).find() %}
                    <li>{{ entry.title }}</li>
                {% endfor %}
            </ul>
        {% endfor %}
{% endfor %}

Instead the output I'm getting is this:

  • Category 1
    • February 2017
      • Event 1
      • Event 4 (in all categories)
    • March 2017
      • Event 1
      • Event 4 (in all categories)
  • Category 2
    • February 2017
      • Event 2
      • Event 5
      • Event 4 (in all categories)
    • March 2017
      • Event 2
      • Event 5
      • Event 4 (in all categories)
  • Category 3
    • February 2017
      • Event 4 (in all categories)
    • March 2017
      • Event 4 (in all categories)

Is there a way to stop the duplicates?

Thanks in advance.

2

In your code, within the {% for eventDate, entries in eventEntries | group("dayStart|date('F Y')") %} loop, in the sub-loop, you are looping over eventEntries.relatedTo(category).find() rather than restricting the entries in that loop to the ones you have already grouped to the date, i.e. in the entries array. That is why you are getting all the entries related to the category under each date heading, instead of just the ones falling under that date.

This should work:

{% set eventCategories = craft.categories.group('events').find() %}
{% set eventEntries = craft.entries.section('event').order('dayStart asc').limit(null) %}
{% for category in eventCategories %}
    <h1>{{ category.title }}</h1>
        {% for eventDate, entries in eventEntries | group("dayStart|date('F Y')") %}
            <h2>{{ eventDate }}</h2>
            <ul>
                {% for entry in entries if (category.id in entry.categoriesField.ids()) %}
                    <li>{{ entry.title }}</li>
                {% endfor %}
            </ul>
        {% endfor %}
{% endfor %}
  • I'm getting an 'Array to string conversion' error when I try this, when I remove '.relatedTo(category).find()' it works but without being filtered by category. What's another way to add a 'relatedTo' parameter to {% for entry in entries %} without errors? – T.Newton Feb 16 '17 at 13:11
  • What's the name of your categories field in the entry? – Steve Rowling Feb 16 '17 at 13:15
  • Try the updated answer. I've added a conditional to only loop through entries which have the current category (from the outer loop) in their categoriesField (put the field handle of your category field here). – Steve Rowling Feb 16 '17 at 13:20
  • My category's field name is 'category'. I tried your updated answer and it worked! Thanks so much, you wonderful human being! – T.Newton Feb 16 '17 at 13:33

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.