Take the 2-minute tour ×
Craft CMS Stack Exchange is a question and answer site for administrators, end users, developers and designers for Craft CMS. It's 100% free, no registration required.

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!

share|improve this question

2 Answers 2

up vote 3 down vote accepted

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.

share|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 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 at 17:19

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.

share|improve this answer
    
I actually think the @carlcs solution is cleaner –  Marion Newlevant Aug 15 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 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 at 17:22

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.