<p>You could just use what you got, loop through the categories and try to grab the descendants for each of them.</p>

<pre><code>{% set entries = craft.entries.relatedTo(category) %}
{% set allMarkets = craft.categories.group('markets').level(1).relatedTo(entries) %}

{% for market in allMarkets %}
    {% set descMarkets = market.getDescendants() %}

    {% if descMarkets %}
        {% for market in descMarkets %}
            {% include '_includes/partial' %}
        {% endfor %}
    {% else %}
        {% include '_includes/partial' %}
    {% endif %}
{% endfor %}
</code></pre>

<p>Another good approach is to "collect" element IDs.</p>

<p>You would basically do the same as in the output loop of the above example, but instead of having the conditionals and extra queries in the output loop, you’d work with element IDs that you merge into an array. You can then query for the categories nicely using the <code>id</code> param in a <code>craft.categories</code> criteria model.</p>

<pre><code>{% set entries = craft.entries.relatedTo(category) %}
{% set topMarkets = craft.categories.group('markets').level(1).relatedTo(entries) %}

{% set allMarketIds = [] %}

{% for market in topMarkets %}
    {% set descMarketIds = craft.categories.descendantOf(market).ids() %}

    {% if descMarketIds %}
        {% set allMarketIds = allMarketIds|merge(descMarketIds) %}
    {% else %}
        {% set allMarketIds = allMarketIds|merge([market.id]) %}
    {% endif %}
{% endfor %}

{% set allMarkets = craft.categories.id(allMarketIds) %}

{% for market in allMarkets %}
    {% include '_includes/partial' %}
{% endfor %}
</code></pre>

<p><strong>Update:</strong></p>

<p>One more approach! I just noticed, that you can simply test whether a category has descendants or not. This should probably be best from a performance point of view.</p>

<pre><code>{% set entries = craft.entries.relatedTo(category) %}
{% set allMarkets = craft.categories.group('markets').relatedTo(entries) %}

{% for market in allMarkets %}
    {% if market.getDescendants().total() == 0 %}
        {% include '_includes/partial' %}
    {% endif %}
{% endfor %}
</code></pre>

CC BY-SA 3.0
2017-03-09T11:20:47.650Z
I got both to work.  I assume the second approach is more efficient - and potentially a best practice?
Hellyar
CC BY-SA 3.0
2017-03-09T12:54:12.260Z
@Hellyar yeah, I like the idea of separating the data fetching and preparation from the actual output as much as possible (approach 2). But I just updated the answer with a new idea. Should be the most efficient and I would probably go with that because of that very reason.
carlcs
CC BY-SA 3.0
2017-03-09T18:12:18.220Z
That's clean.  But, I am going to try and see if I can apply the array approach elsewhere on the site I'm building.  Thanks.
Hellyar
CC BY-SA 3.0
2017-12-19T13:19:07.700Z
It’s also possible to just check if `entry.hasDescendants` is false. This feels a bit cleaner, although it doesn’t seem to save any queries, as I’d hoped it might.
Dom Stubbs
CC BY-SA 3.0
2017-03-08T01:38:37.050Z
2017-03-09T12:49:52.087Z
2017-03-09T12:49:52.087Z
carlcs
<p>I am going to try this again...</p>

<p>I have a page for a category (<code>country</code>) with all the entries that match that country.   </p>

<p>I have buttons that allow you to filter the entries using categories from a second category group ('market').  </p>

<p><strong>All, I want to do is list the markets to make the filter buttons.<br>
BUT, I don't want to list the parent if their is a child.  And, there is not always a child.</strong>  </p>

<p><a href="https://i.sstatic.net/qIn1O.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/qIn1O.png" alt="enter image description here"></a></p>

<p>This is how I have things setup.  </p>

<pre><code>{% set entries = craft.entries.relatedTo(category).find() %}
{% set markets = craft.categories.group('markets').relatedTo(entries).find() %}
</code></pre>

<p>But, this prints both the parent and child of a market. I don't want to print the parent if there is a child.  </p>

<p>Addling <code>level(x)</code> does not work because then it leaves out those markets that might be x+1 or x-1.  </p>

<p>And adding <code>last()</code> did not work.  </p>

<p>This has to be possible.  It's killing me. </p>

<templating>
Categories in a RelatedTo - How do I not list the parent if there is a child?
# Categories in a RelatedTo - How do I not list the parent if there is a child?

(Asked by: username_0 on 2017-03-07)

I am going to try this again...
I have a page for a category (country) with all the entries that match that country.   
I have buttons that allow you to filter the entries using categories from a second category group ('market').  
All, I want to do is list the markets to make the filter buttons.
BUT, I don't want to list the parent if their is a child.  And, there is not always a child. 

This is how I have things setup.  
{% set entries = craft.entries.relatedTo(category).find() %}
{% set markets = craft.categories.group('markets').relatedTo(entries).find() %}

But, this prints both the parent and child of a market. I don't want to print the parent if there is a child.  
Addling level(x) does not work because then it leaves out those markets that might be x+1 or x-1.  
And adding last() did not work.  
This has to be possible.  It's killing me.

**Tags:** templating

---

## 1 answers

### Answer by username_1 on 2017-03-08. Score: 3 | Accepted answer

You could just use what you got, loop through the categories and try to grab the descendants for each of them.
{% set entries = craft.entries.relatedTo(category) %}
{% set allMarkets = craft.categories.group('markets').level(1).relatedTo(entries) %}

{% for market in allMarkets %}
    {% set descMarkets = market.getDescendants() %}

    {% if descMarkets %}
        {% for market in descMarkets %}
            {% include '_includes/partial' %}
        {% endfor %}
    {% else %}
        {% include '_includes/partial' %}
    {% endif %}
{% endfor %}

Another good approach is to "collect" element IDs.
You would basically do the same as in the output loop of the above example, but instead of having the conditionals and extra queries in the output loop, you’d work with element IDs that you merge into an array. You can then query for the categories nicely using the id param in a craft.categories criteria model.
{% set entries = craft.entries.relatedTo(category) %}
{% set topMarkets = craft.categories.group('markets').level(1).relatedTo(entries) %}

{% set allMarketIds = [] %}

{% for market in topMarkets %}
    {% set descMarketIds = craft.categories.descendantOf(market).ids() %}

    {% if descMarketIds %}
        {% set allMarketIds = allMarketIds|merge(descMarketIds) %}
    {% else %}
        {% set allMarketIds = allMarketIds|merge([market.id]) %}
    {% endif %}
{% endfor %}

{% set allMarkets = craft.categories.id(allMarketIds) %}

{% for market in allMarkets %}
    {% include '_includes/partial' %}
{% endfor %}

Update:
One more approach! I just noticed, that you can simply test whether a category has descendants or not. This should probably be best from a performance point of view.
{% set entries = craft.entries.relatedTo(category) %}
{% set allMarkets = craft.categories.group('markets').relatedTo(entries) %}

{% for market in allMarkets %}
    {% if market.getDescendants().total() == 0 %}
        {% include '_includes/partial' %}
    {% endif %}
{% endfor %}

> **Comments:**
> **username_0**: I got both to work.  I assume the second approach is more efficient - and potentially a best practice?  
> **username_1**: @Hellyar yeah, I like the idea of separating the data fetching and preparation from the actual output as much as possible (approach 2). But I just updated the answer with a new idea. Should be the most efficient and I would probably go with that because of that very reason.  
> **username_0**: That's clean.  But, I am going to try and see if I can apply the array approach elsewhere on the site I'm building.  Thanks.  
> **username_2**: It’s also possible to just check if `entry.hasDescendants` is false. This feels a bit cleaner, although it doesn’t seem to save any queries, as I’d hoped it might.  

---

