2

I'm trying to display a list of names alphabetically ordered. This is working fine, but I also want to check if the name is intoCollection or not (using a Lightswitch).

If it is intoCollection, it displays the letter + the list of names related. If there is no name related to the letter, I need to display nothing (= no letter).

Here is the code which seems good for me, but is not correct:

{% set artists = craft.entries.section('artists').limit(null).order('title') %}
{% for letter, letterEntries in artists | group('title|upper|slice(0, 1)') %}

    {% for entry in letterEntries %}
        {% if entry.intoCollection | length %}

        <div>
            <h3>{{ letter | upper }}</h3>
            <ul> 
            {% for entry in letterEntries %}
                {% if entry.intoCollection %}
                    <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
                {% endif %}
            {% endfor %}
            </ul>
        </div>

        {% endif %}
    {% endfor %}

{% endfor %}

It displays letters duplicated, but also letters that contain no names...

Any idea? Thanks!

4

You'd further filter your returned artist entries down like this:

{% set artists = craft.entries.section('artists').intoCollection('1') %}

Then remove all the unnecessary "intoCollection" conditionals in your loop.

| improve this answer | |
  • I didn't know I can do like this. I'm a beginner so I thought it was more complicated than it is ;-) Thanks for your answer, I'll take note of this correct way to filter! – Romain Poirier Aug 15 '14 at 17:04
  • @romain this is a simple answer to your actual problem, but marion's answer is actually the better answer to your problem description, that "check if child of loop in loop" kind of thing. – carlcs Aug 15 '14 at 17:19
2

You have {% for entry in letterEntries %} twice, one loop inside the other, which is going to give you things twice. Also, since intoCollection is a Lightswitch Field you test it with {% if entry.intoCollection %} (no |length) Try this:

{% set artists = craft.entries.section('artists').limit(null).order('title') %}
{% for letter, letterEntries in artists | group('title|upper|slice(0, 1)') %}

  {# see if any of the entries is intoCollection #}
  {% set isIntoCollection = false %}
  {% for entry in letterEntries %}
    {% if entry.intoCollection %}
      {% set isIntoCollection = true %}
      {# break here #}
    {% endif %}
  {% endfor %}

  {# now display them #}
  {% if isIntoCollection %}
    <div>
      <h3>{{ letter | upper }}</h3>
      <ul> 
        {% for entry in letterEntries %}
          {% if entry.intoCollection %}
            <li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
          {% endif %}
        {% endfor %}
      </ul>
    </div>
  {% endif %}

{% endfor %}

You can break the loop at {# break here #} if you have the mnbreakandcontinue plugin. It's not necessary, just a potential optimization.

| improve this answer | |
  • I actually think the @carlcs solution is cleaner – Marion Newlevant Aug 15 '14 at 16:56
  • Thanks! It works, but it does not preserve my loop.index which I use for something else (close my divs rows): it seems to count everything, if entry.intoCollection or not. After one test with few entries, it jumps from 5 to 7. – Romain Poirier Aug 15 '14 at 16:57
  • Yes marion, but this solution actually fits the question title better AND you could do nice things for those letters that are empty. – carlcs Aug 15 '14 at 17:22

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.