1

I have a structure section, which allows categories to be assigned to the final descendant. I'm trying to list the entries by category, whilst including the parent structure entries (so the hierarchy is maintained).

Structure entries

  • Womens
    • Type 1
      • Item 1 (category green)
      • Item 2 (category blue)
      • Item 3 (category red)
    • Type 2
      • Item 4 (category blue)
      • Item 5 (category red)
      • Item 6 (category blue)
  • Mens
    • Type 3
      • Item 7 (category red)
      • Item 8 (category blue)
      • Item 9 (category blue)
    • Type 4
      • Item 10 (category blue)
      • Item 11 (category red)
      • Item 12 (category green)

––––––––––––––––––––––––––––

I’m trying to create a nested list of this structure, viewed by category, which excludes parents with no descendants within the looped category.

Desired category view

  • Category Green
    • Womens
      • Type 1
        • Item 1 (category green)
    • Mens
      • Type 4
        • Item 12 (category green)
  • Category Blue
    • Womens
      • Type 1
        • Item 2 (category blue)
      • Type 2
        • Item 4 (category blue)
        • Item 6 (category blue)
    • Mens
      • Type 3
        • Item 8 (category blue)
        • Item 9 (category blue)
      • Type 4
        • Item 10 (category blue)
  • Category Red
    • Womens
      • Type 1
        • Item 3 (category red)
      • Type 2
        • Item 5 (category red)
    • Mens
      • Type 3
        • Item 7 (category red)
      • Type 4
        • Item 11 (category red)

––––––––––––––––––––––––––––

My attempt

This comes close, however parent structure elements appear, event if they have no descendants in the corresponding category.

{% set productCategories = craft.categories.group('products') %}
{% set structure = craft.entries.section('products').level(1) %}

{% macro recursiveChildren(page, category) %}
    {% if page.hasDescendants %}
    <ul>
        {% for subpage in page.children %}
            {% if subpage.level == '2' %}
                <li>
                    {{ subpage.link }}
                    {{ _self.recursiveChildren(subpage, category) }}                    
                </li>
            {% endif %}
            {% if subpage.level == '3' and category == subpage.productCategory|first %}
                <li>
                    {{ subpage.link }}
                </li>
            {% endif %}
        {% endfor %}
    </ul>
    {% endif %}
{% endmacro %}

<ul>
{% for category in productCategories %}
        <li>{{category.title}}
        {% set thisCat = category.title %}
            <ul>
                {% for entry in structure %}
                    {% if entry.hasDescendants %}
                        <li>{{entry.title}}
                            {{ _self.recursiveChildren(entry, thisCat) }}
                        </li>
                    {% endif%}
                {% endfor %}
            </ul>
        </li>
{% endfor %}
</ul>

returns:

  • Category Green
    • Womens
      • Type 1
        • Item 1 (category green)
      • Type 2
    • Mens
      • Type 3
      • Type 4
        • Item 12 (category green)
  • Category Blue
    • Womens
      • Type 1
        • Item 2 (category blue)
      • Type 2
        • Item 4 (category blue)
        • Item 6 (category blue)
    • Mens
      • Type 3
        • Item 8 (category blue)
        • Item 9 (category blue)
      • Type 4
        • Item 10 (category blue)
  • Category Red
    • Womens
      • Type 1
        • Item 3 (category red)
      • Type 2
        • Item 5 (category red)
    • Mens
      • Type 3
        • Item 7 (category red)
      • Type 4
        • Item 11 (category red)

––––––––––––––––––––––––––––

I would welcome and tips, or suggestions to achieve this.

How can I omit the parents with no children?

How can I optimise the code?

Many thanks!

EDIT ––––––––––––––––––––––––––––

I've added a couple of additional for loops to check if there are descendants within matching categories to omit parents with no children. It works but my code feels very clunky and heavy.

In time I plan to rewrite/refactor the following to improve the performance.

{% macro recursiveCats(page, category) %}
    {% if page.hasDescendants %}
    {% set entryGrandchildren = page.getDescendants(2) %}
        {% for entry in entryGrandchildren if entry.productCategory|first == category %}
            <ul class="dropdown">
                {% for subpage in page.children %}
                    {% if subpage.level == '2' %}
                        {% if subpage.hasDescendants %}
                        {% set entryChildren = subpage.getDescendants(1) %}

                            {% for entry in entryChildren if entry.productCategory|first == category %}
                                {% if loop.first %}
                                    <li>
                                        {{ subpage.link }}{#{{ subpage.productCategory|first }}{{category}}#}
                                        {{ _self.recursiveCats(subpage, category) }}                    
                                    </li>
                                {% endif %}
                            {% endfor %}

                        {% endif%}
                    {% endif %}
                    {% if subpage.level == '3' and category == subpage.productCategory|first %}                 
                            <li>
                                {{ subpage.link }}
                            </li>
                    {% endif %}
                {% endfor %}
            </ul>
        {% endfor %}
    {% endif %}
{% endmacro %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.