<p>Collecting all of the categories' ancestors is probably the way to go in that case. So the solution you already posted within your question is more or less the same as I was about to post.</p>

<p>Instead of having a conditional in the output loop, you could also prepare an array of your bottom level category models using Craft's <a href="http://buildwithcraft.com/docs/templating/filters#without" rel="nofollow"><code>without</code></a> filter (I always try to separate output from query / logic blocks in my templates).</p>

<p>This works with any number of category levels.</p>

<pre><code>{% set allCategories = craft.categories.relatedTo(entry) %}

{% set ancestorCatIds = [] %}
{% for category in allCategories %}
    {% set ancestorCatIds = ancestorCatIds|merge(category.ancestors.ids()) %}
{% endfor %}

{% set bottomCatIds = allCategories.ids()|without(ancestorCatIds) %}
{% set bottomCategories = craft.categories.id(bottomCatIds) %}

&lt;ul&gt;
    {% for category in bottomCategories %}
        &lt;li&gt;{{ macros.catBreadcrumbs(category) }}&lt;/li&gt;
    {% endfor %}
&lt;/ul&gt;
</code></pre>

<p>I made a macro that outputs the category breadcrumbs, to have even less logic in the output block.</p>

<pre><code>{% macro catBreadcrumbs(category) %}
    {% set ancestorCategories = category.ancestors.find() %}
    {% set ancestorCategories = ancestorCategories|merge([category]) %}
    {{ ancestorCategories|join(' &gt; ') }}
{% endmacro %}
</code></pre>

CC BY-SA 3.0
2015-04-20T08:12:48.503Z
2015-04-20T09:22:09.937Z
2015-04-20T09:22:09.937Z
carlcs
<p>I also had to make an array of categories that have children related to the entry. Then hide those categories when running the output loop. This is as concise as I could make the code. Assuming your category field name is <code>myCats</code>, this will do the trick:</p>

<pre><code>{% set hiddenCats = [] %}
{% for category in entry.myCats.level(2) %}
  {% set hiddenCats = hiddenCats|merge([category.parent.id]) %}
{% endfor %}

&lt;ul&gt;
  {% for category in entry.myCats if category.id not in hiddenCats %}
    &lt;li&gt;
      {% if category.parent %}
        {{ category.parent.title }} &amp;gt;
      {% endif %}

      {{ category.title }}
    &lt;/li&gt;
  {% endfor %}
&lt;/ul&gt;
</code></pre>

CC BY-SA 3.0
2015-04-20T08:23:41.997Z
What if category "B" does actually have child categories, but they're just not related to the current entry.
carlcs
CC BY-SA 3.0
2015-04-20T11:00:35.243Z
Oops. I didn't see that we were dealing with a list of categories related to an entry. I'll revise my answer.
Alex Roper
CC BY-SA 3.0
2015-04-20T07:47:06.233Z
2015-04-20T11:11:35.043Z
2015-04-20T11:11:35.043Z
Alex Roper
<p>I'm struggling with how to do this in Twig... I feel like it would be easier in a full programming language.</p>

<p>If an entry's categories look like this:</p>

<pre><code>A
    - A1
    - A2
B
C
    - C1
</code></pre>

<p>I need to output a list like this:</p>

<pre><code>A &gt; A1
A &gt; A2
B
C &gt; C1
</code></pre>

<p>I can't seem to figure out how to avoid printing all the top-level categories on their own. This is what I've managed to output:</p>

<pre><code>A
A &gt; A1
A &gt; A2
B
C
C &gt; C1
</code></pre>

<p>I have a feeling I'm going to feel dumb when someone answers this, but any help is appreciated.</p>

<hr>

<p>Edit: I've found <em>a</em> solution.</p>

<p>Before listing the categories, I run a <code>for</code> loop on just the entry's level 2 categories and collect their parents' IDs using an empty array and the <code>merge</code> filter. Then, when listing the categories, I put a conditional so that level 1 categories are not listed if their ID is in the array.</p>

<p>It seems an awkward way to do it, and I'm still interested in better solutions.</p>

<categories>
Display an entry's level 1 categories only if the entry is not related to any of that category's children
# Display an entry's level 1 categories only if the entry is not related to any of that category's children

(Asked by: username_0 on 2015-04-20)

I'm struggling with how to do this in Twig... I feel like it would be easier in a full programming language.
If an entry's categories look like this:
A
    - A1
    - A2
B
C
    - C1

I need to output a list like this:
A > A1
A > A2
B
C > C1

I can't seem to figure out how to avoid printing all the top-level categories on their own. This is what I've managed to output:
A
A > A1
A > A2
B
C
C > C1

I have a feeling I'm going to feel dumb when someone answers this, but any help is appreciated.

Edit: I've found a solution.
Before listing the categories, I run a for loop on just the entry's level 2 categories and collect their parents' IDs using an empty array and the merge filter. Then, when listing the categories, I put a conditional so that level 1 categories are not listed if their ID is in the array.
It seems an awkward way to do it, and I'm still interested in better solutions.

**Tags:** categories

---

## 2 answers

### Answer by username_1 on 2015-04-20. Score: 2 | Accepted answer

Collecting all of the categories' ancestors is probably the way to go in that case. So the solution you already posted within your question is more or less the same as I was about to post.
Instead of having a conditional in the output loop, you could also prepare an array of your bottom level category models using Craft's without filter (I always try to separate output from query / logic blocks in my templates).
This works with any number of category levels.
{% set allCategories = craft.categories.relatedTo(entry) %}

{% set ancestorCatIds = [] %}
{% for category in allCategories %}
    {% set ancestorCatIds = ancestorCatIds|merge(category.ancestors.ids()) %}
{% endfor %}

{% set bottomCatIds = allCategories.ids()|without(ancestorCatIds) %}
{% set bottomCategories = craft.categories.id(bottomCatIds) %}


    {% for category in bottomCategories %}
        {{ macros.catBreadcrumbs(category) }}
    {% endfor %}


I made a macro that outputs the category breadcrumbs, to have even less logic in the output block.
{% macro catBreadcrumbs(category) %}
    {% set ancestorCategories = category.ancestors.find() %}
    {% set ancestorCategories = ancestorCategories|merge([category]) %}
    {{ ancestorCategories|join(' > ') }}
{% endmacro %}


---

### Answer by username_2 on 2015-04-20. Score: 1

I also had to make an array of categories that have children related to the entry. Then hide those categories when running the output loop. This is as concise as I could make the code. Assuming your category field name is myCats, this will do the trick:
{% set hiddenCats = [] %}
{% for category in entry.myCats.level(2) %}
  {% set hiddenCats = hiddenCats|merge([category.parent.id]) %}
{% endfor %}


  {% for category in entry.myCats if category.id not in hiddenCats %}
    
      {% if category.parent %}
        {{ category.parent.title }} >
      {% endif %}

      {{ category.title }}
    
  {% endfor %}

> **Comments:**
> **username_1**: What if category "B" does actually have child categories, but they're just not related to the current entry.  
> **username_2**: Oops. I didn't see that we were dealing with a list of categories related to an entry. I'll revise my answer.  

---

