2

I have a channel section called Members. I have 2 category groups (categoriesMembres & cantons).

My goal: show entries only related to a specific category in categoriesMembres and loop through the cantons:

Canton1

  • entry 1
  • entry 2
  • etc.

Canton2

  • entry 3
  • entry 4
  • etc.

Right now the code below display it like that:

Canton1

  • entry 1
  • entry 2
  • entry 3
  • entry 4

Canton2

  • entry 1
  • entry 2
  • entry 3
  • entry 4

The code (I stripped out html for clarity)

{% set membersCat = craft.categories.group('categoriesMembres').title('Membre').first() %}
{% set entries = craft.entries.section('listeMembres').relatedTo(membersCat) %}
{% set cantonsCat = craft.categories.group('cantons').relatedTo(entries) %}

{% for canton in cantonsCat %}
   {{ canton.title }}
   {% for row in entries|batch(3) %}
    {% for entry in row %}
     {{ entry.title }}
    {% endfor %}
    {% endfor %}
    {% endfor %}

What am I overseeing or doing wrong?

2

You missed to filter for entries related to your "Canton" category only within your cantons loop. Add another ElementCriteriaModel and get entries related to both membersCat and canton:

{% for canton in cantonsCat %}
    {% set entriesInCanton = craft.entries.section('listeMembres').relatedTo('and', membersCat, canton) %}    
    {% for row in entriesInCanton|batch(3) %}
        ...
    {% endfor %}
{% endfor %}

Another approach (only works if there's one "Canton" max per entry!) would be to make use of Craft's group filter. This is probably the better way to solve your problem, because it doesn't add extra DB queries for each "Canton" iterated over in your loop.

{% set membersCat = craft.categories.group('categoriesMembres').title('Membre').first() %}
{% set cantonsCats = craft.categories.group('cantons') %}
{% set cantonsCatsInUse = craft.categories.group('cantons').relatedTo(entries) %}

{% set entries = craft.entries.section('listeMembres').relatedTo('and', membersCat, cantonsCats) %}
{% set entriesByCanton = entries|group('myCantonCategoryField.first()') %}

{% for canton, entriesInCanton in entriesByCanton %}
    {% for row in entriesInCanton|batch(3) %}
        ...
    {% endfor %}
{% endfor %}

This probably won't output the cantons in the sort order you whish, but this fortunatelly can be solved easily.

{% set entriesByCanton = entriesByCanton|supersort('ksort') %}
  • The second approach is best as I have only one canton for each entry and it truly save DB queries. Thanks carlcs! – jjem May 29 '15 at 9:35

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.