twigで再帰呼び出しができると知りました
そのような処理が必要なときはできるだけPHPで前処理してテンプレートに渡すようにしてましたが、twigで処理できるならそのほうがスマートな場合も多そうです
きっかけはECCUBE4のソース
カテゴリを表示している場所で再帰呼び出しをしています
src/Eccube/Resource/template/default/Block/category_nav_pc.twig
{% set Categories = repository('Eccube\\Entity\\Category').getList() %}
{% macro tree(Category) %}
{% from _self import tree %}
<a href="{{ url('product_list') }}?category_id={{ Category.id }}">
{{ Category.name }}
</a>
{% if Category.children|length > 0 %}
<ul>
{% for ChildCategory in Category.children %}
<li>
{{ tree(ChildCategory) }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{# @see https://github.com/bolt/bolt/pull/2388 #}
{% from _self import tree %}
<div class="ec-categoryNaviRole">
<div class="ec-itemNav">
<ul class="ec-itemNav__nav">
{% for Category in Categories %}
<li>
{{ tree(Category) }}
</li>
{% endfor %}
</ul>
</div>
</div>
上記のソースでは前半部分でmacroを定義して、後半でそれを一回呼び出してます
呼びされたmacroの中でさらにまた自分自身を呼び出すことで、カテゴリの深さのぶんだけ再帰的に処理されるようになっています
