<ol>
{% for block in entry.neoField.level(1).all() %}
{% switch block.type.handle %}
{% case 'someBlockType' %}
<li>
{{ block.someField }}
{% if block.children.all() is not empty %}
...
{% endif %}
</li>
{% case ...
{% endswitch %}
{% endfor %}
</ol>
This is typically the most you'd need to know. Similar to how Matrix fields work, but with a notable difference. For Neo fields that have child blocks, you will first need to filter for blocks on the first level. It's essentially the same API as the craft.entries()
element query.
<ol>
{% nav block in entry.neoField.all() %}
<li>
{{ block.someField }}
{% ifchildren %}
<ol>
{% children %}
</ol>
{% endifchildren %}
</li>
{% endnav %}
</ol>
Because Neo blocks have a level
attribute, Neo fields are compatible with the {% nav %}
tag.
For a more in-depth breakdown of templating for Neo, see this issue.