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?
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 %}