PHP
twig

twig2系で再帰処理

twigで再帰処理を使う場合はmacroを使うと楽だと思います。
twig1系ではtwig で再帰処理の通りに実装すれば大丈夫です。

しかし、twig2系だと_selfはテンプレート名を返してきてしまうため、_self.foobar()みたいな呼び出しができなくなってしまった・・・。

stackoverflowによるとimport文を使えばいいみたい。
Twig Runtime Error: Impossible to invoke a method (“test”) on a string variable

この記事を参考にして、twig2系での再起処理を実装してみた。
ポイントとしてはmacrosを引数で渡すこと。
macroで定義したrecursiveCategoriesの中ではimportしたmacrosを参照できないため、仕方なく引数で渡すようにしている。
もっといい方法があれば良いのだが・・・。

{% import _self as macros %}

{% block body %}
        {% macro recursiveCategories(Category, macros) %}
            {% if Category.hasChildNodes() %}
                <ul>
                    {% for child in Category.childNodes() %}
                        <li>{{ child.name }}</li>
                        {{ macros.recursiveCategories(child) }}
                    {% endfor %}
                </ul>
            {% endif %}
        {% endmacro %}

        {% if Category.hasChildNodes() %}
        <ul>
            {% for ChildCategory in Category.childNodes() %}         
                <li>{{ ChildCategory.name }}</li>
                {{ macros.recursiveCategories(ChildCategory, macros) }}         
            {% endfor %}
        </ul>
        {% endif %}
{% endblock}

参考
https://github.com/symfony/demo/issues/322