I need to show a list of Child Categories which only have Entries attached.

From about 6 different solutions here, I have assembled the following. It works perfectly on a Section that has < 200 Entries with a Category Group that contains 50 Parent Cats that each may have up to 10 Child Cats.

My concern is that with a larger Section (3,200 entries, yet to be imported into Craft) it will break down, timeout, etc. because in order for this to work, ALL the Entries from a Section must be present in the Array for the Categories to check Relations against.

For brevity and clarity, the following URL structure is required by the client for several reasons...

URL = /alpha/yadda/news
syntax = /[parent-category]/identifier/[section]

Section = News
Category Group = 1
Category Examples =
alpha
    alpha-1
    alpha-2
    alpha-3
beta
    beta-1
    beta-2
    beta-3
    beta-4
etc....

Based on that, here is what I've assembed that works great for 200 entries in News. It outputs a list of Child categories that only have News entries, based on the Parent's Category Slug in segment 1:

{# 1. find ALL the entry ids for a channel #}
{% set entryIds = craft.entries.section('news').limit(null).ids() %}

{# 2. find all the cats in Group 1 related to those entries #}
{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).limit(null).find() %}

{# 3. set var from URL seg1 and use to get CatModel Object: catParent #}
{% set parentSlug = craft.request.getSegment(1) %}
{% set catParent = craft.categories.slug(parentSlug).first() %}

{# 4. using catParent, get child cats #}
{% set subCategories = craft.categories.descendantOf(catParent) %}

{# 5. loop through cats found matching entries in step 2 
        then subloop through this Parent Cat's descendants for match #}
{% for category in categories %}
    {% set currentCat = category.title %}
    {% for subCat in subCategories %}
        {% if subCat.title == currentCat %}
            <li>{{ subCat.title }}</li>
        {% endif %}
    {% endfor %}
{% endfor %}


Again, this all works...for 200 entries in News. But I don't see how it's scalable for the 3,200 blog entries that will be imported.

Just seems like there must be a better, more efficient way to display a list of Categories (or only descendants of a specific Parent Cat) that have Entries attached?

Having the need for a similar setup to yourself, I came up with a more efficient example below.

{% set entryIds = craft.entries.section('news').status('live').limit(null).ids() %}

{% set parentSlug = craft.request.getSegment(1) %}
{% set catParent = craft.categories.slug(parentSlug).first() %}

{% set categories = craft.categories.relatedTo({ sourceElement: entryIds }).groupId(1).limit(null).descendantOf(catParent).find() %}

{% nav category in categories %}
    <li>
        <a href="#">{{ category.title }}</a>
        {% ifchildren %}
            <ul>
                {% children %}
            </ul>
        {% endifchildren %}
    </li>
{% endnav %}
  • This is awesome! I no longer work on the original project for which I posted this, but I hope your much better solution helps others! – Shane Robinson Aug 13 at 17:51

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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