Search code examples
loopstwiggrav

Twig for loop - output only parent if any children exists


These lines prints all categories and the products within. But if the category has no products the category title is still printed.

{% for category in categories %}
  <h1>{{ category.title }}</h1>
  {% for product in products if products.category|first == category.title|lower %}
    <h2>{{ product.title }}</h2>
  {% endfor %}
{% endfor %}

How can I optimize this so category titles are printed only when the category contains products?


Solution

  • There are (imo) 2 solution for this. The first one is pure twig-based, but is the worst of the two methods.

    In order to skip categories without children, this would require a second loop and flag variable to determine wether to skip the category or not. As twig can't break out of loops this means u would need to foreach the products twice completely

    {% for category in categories %}
      {% set flag = false %}
      {% for product in products if products.category|first == category.title|lower %}   
        {% set flag = true %}
      {% endfor %}
      {% if flag %}
          <h1>{{ category.title }}</h1>
          {% for product in products if products.category|first == category.title|lower %}
            <h2>{{ product.title }}</h2>
          {% endfor %}
      {% endif %}
    {% endfor %}
    

    The second and better solution is just to add an extra method to your category-model and do something like

    {% for category in categories if category.hasProducts() %}
      <h1>{{ category.title }}</h1>
      {% for product in products if products.category|first == category.title|lower %}
        <h2>{{ product.title }}</h2>
      {% endfor %}
    {% endfor %}