2

I have a section called "Events" and an Entries field, we'll call myEntriesField to select related entries from another channel called "Exhibitors"

On the Events page, I need to display the related Exhibitors grouped by their categories. And if there are no related Exhibitors in said Event, I need to hide the surrounding html that displays the category title etc.

I have this in my template:

        {% set theListings = entry.myEntriesField %}



        {% set thisCategory = 
             theListings.relatedTo(craft.categories.slug('the-category-i-need')) 
        %}

        {% if thisCategory | length %}
        <div class="section listings">
            <h2>Category Title</h2>
            <div class="the-listings">
            {% for theEntry in thisCategory %}
                <div class="item">
                    <h3>{{ theEntry.title }}</h3>
                    ...more entry data stuff...
                    </div>
                </div>
            {% endfor %}
            </div>
        </div>
        {% endif %}



        {% set thisOtherCategory = 
             theListings.relatedTo(craft.categories.slug('the-next-category-i-need')) 
        %}

        {% if thisOtherCategory | length %}
        <div class="section listings">
            <h2>Category Title</h2>
            <div class="the-listings">
            {% for otherEntry in thisOtherCategory %}
                <div class="item">
                    <h3>{{ otherEntry.title }}</h3>
                    ...more entry data stuff...
                    </div>
                </div>
            {% endfor %}
            </div>
        </div>
        {% endif %}

But this displaying ALL Exhibitors, grouped by their categories, rather than just the related Exhibitors selected in the Event entry.

Any ideas what I am missing here?

2 Answers 2

3

Start by looping thru each category. Say, all categories in a category group called "eventsCategories." Then find entries related to each category (if any).

{# loop through each of the categories #}
{% for category in craft.categories.group('eventsCategories') %}

  {# find the exhibitor entries that are related to both the Event entry and category #}
  {% set categoryListings = craft.entries({
    section: 'exhibitors',
    relatedTo: ['and',
      { sourceElement: entry, field: 'myEntriesField' },
      { targetElement: category, field: 'myCategoriesField' }
    ]
  }) %}

  {# Only show this category if there were any related exhibitors #}
  {% if categoryListings|length %}

    <h2>{{ category.title }}</h2>

    {% for listing in categoryListings %}
      <h3>{{ listing.title}}</h3>
    {% endfor %}

  {% endif %}
{% endfor %}
4
  • Thank you! I tested with this, but it is giving me the same result. I'm getting ALL of the Exhibitors, instead of just those selected in the Event entry via myEntriesField :/ Commented Mar 2, 2017 at 16:26
  • Thanks for fixing it, Brad. I should have tested that code before I posted. ;)
    – Alex Roper
    Commented Mar 3, 2017 at 10:22
  • @AlexRoper no prob, that was a weird one, because entry.myEntriesField is an ElementCriteriaModel that already has a relatedTo param set on it, so your code was actually overriding it. Commented Mar 3, 2017 at 11:46
  • You guys rock!!! Thanks so much, this works perfectly :) Commented Mar 6, 2017 at 16:23
2

Craft’s |group filter can be used here.

I’m going to assume that the Categories custom field on your Exhibitor entries is called myCategoriesField.

{% set groupedListings = entry.myEntriesField.find()|group('myCategoriesField.first.title')

That will give you an array of grouped Exhibitor entries, grouped by their related category titles. For example, it might look like:

[
    'Category A Title' => [
        ExhibitorEntry1,
        ExhibitorEntry2
    'Category B Title' => [
        ExhibitorEntry3,
        ExhibitorEntry4
]

Then you can loop through the grouped entries like so:

{% for categoryTitle, listings in groupedListings %}
    <div class="section listings">
        <h2>{{ categoryTitle }}</h2>
        <div class="the-listings">
            {% for listing in listings %}
                <div class="item">
                    <h3>{{ listing.title }}</h3>
                    ...more entry data stuff...
                </div>
            {% endfor %}
        </div>
    </div>
{% endfor %}

If you want to sort the category titles alphabetically, it gets slightly more complicated, but still doable:

{# Get the list of category titles from the groupedListings keys, and sort them #}
{% set sortedCategoryTitles = groupedListings|keys|sort %}

{# Loop through the sorted category titles #}
{% for categoryTitle in sortedCategoryTitles %}

    {# Now get the listings for this category title from the groupedListings array #}
    {% set listings = groupedListings[categoryTitle] %}

    {# Now display the category and its listings like normal... #}
    <div class="section listings">
        <h2>{{ categoryTitle }}</h2>
        <div class="the-listings">
            {% for listing in listings %}
                <div class="item">
                    <h3>{{ listing.title }}</h3>
                    ...more entry data stuff...
                </div>
            {% endfor %}
        </div>
    </div>
{% endfor %}
2
  • Sweet! That's just what I was needing! The only thing I forgot to mention though, is some of the Exhibitors are in multiple categories. But this is only displaying each Exhibitor in only 1 category each. e.g.: Exhibitor A is in Category 1, 2 & 3, but is only showing up in Category 1. Commented Mar 2, 2017 at 20:30
  • @ByteMyPixel Ah, in that case, Alex's solution is better. I just tweaked it a bit - should work for you now. Commented Mar 3, 2017 at 0:09

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.