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!

0

2 Answers 2

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.

2
  • 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 P.
    Commented Aug 15, 2014 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
    Commented Aug 15, 2014 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.

3
  • I actually think the @carlcs solution is cleaner Commented Aug 15, 2014 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 P.
    Commented Aug 15, 2014 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
    Commented Aug 15, 2014 at 17:22

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.