1

So I have a section called children and these are related to various other entries include users. I am fetching all the children for the currentUser like so and eager-loading all the other relationships.

{% set childrenQuery = craft.entries
  .section('children')
  .relatedTo({
  sourceElement: currentUser,
  field: 'relatedChildren'
})
  .with([
  'associatedTerm',
  'tuitionClass',
  'tuitionClass.location'
]) %}

{% set children = childrenQuery.all() %}

What I then want to do is split out children in to 'Active' and 'Inactive' depending on if the related field associatedTerm is live.

I can do this fine like this;

Children (active)<br />
<ul class="list-disc mb-6">
  {% for child in children if child.associatedTerm|length %}
    <li>{{ child.firstName }} {{ child.surname }}</li>
    <li>{{ child.tuitionClass[0] }}</li>
    <li>{{ child.associatedTerm[0] }}</li>
    <li>{{ child.tuitionClass[0].location[0] }}</li>
  {% endfor %}
</ul>

Children Inactive ()<br />
  <ul class="list-disc mb-6">
    {% for child in children if not child.associatedTerm|length %}
      <li>{{ child.firstName }} {{ child.surname }}</li>
    {% endfor %}
  </ul>

However, what I want to do is actually do this logic first, so I can then wrap the active/inactive blocks into if statements, if there are in fact any active or inactive children as I have other code (headings and text) I want to show within the block and not appear at all if they are no entries.

So I am stuck on how to do this {% for child in children if not child.associatedTerm|length %} without a for loop and just check if there are any entries that exist.

I can achieve it like this; but it feels a little weird.

{% set childrenAreInactive = '' %}
{% for child in children if not child.associatedTerm|length %}
  {% set childrenAreInactive = 1 %}
{% endfor %}

Anyone have any ideas for a better method?

2

You're looking for the filter filter: https://docs.craftcms.com/v3/dev/filters.html#filter

Specifically something like this (untested):

{% set activeChildren = children|filter(child => child.associatedTerm|length) %}
{% set inactiveChildren = children|filter(child => child.associatedTerm|length == 0) %}

You now have two unique arrays to do with as you please:

{% if activeChildren|length %}
   <h2>You have active children</h2>
{% endif %}
<p class="{{ inactiveChildren|length ? 'inactiveChildren' }}">Hi there</p>

Whenever you get the sneaky feeling that a loop is overkill, look to map filter and reduce: these 3 methods are all like loops in disguise, in that they iterate through arrays and return something new based on the logic you supply.

| improve this answer | |
  • That's great. Thanks @jamessmith - the filter looks like a great approach. – Terry Upton Jul 7 at 11:02

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.