This is an example of our "quick and dirty" menu macro we used in older projects. It's recursive so it can have as many levels as you want and will only fetch enabled entries. For mobile devices the parent entry is rendered in the "child" menu as well because otherwise you won't be able to access parent entries with children.
It looks a bit overwhelming at first, because we had many things to consider but it's relative easy
<!--
menuCategory: [mainmenu/footermenu/topmenu/descendants]
currentPage: the current entry of the loop
includeStartPage: bool if the start page should be included to the menu
level: current level, integer
parent: parent entry if there is one
original: the original current entry from craft
showParentPage: if the parent page should appear in current menu level for mobile devices
-->
{% macro menu(menuCategory, currentPage, includeStartpage, level = 1, parent = null, original = null, showParentPage = null) %}
{% set originalPage = (original)? original : currentPage %}
{% set activeClass = '' %}
{% if original is not null and currentPage is not null and original.parent is not null %}
{% if original.parent.id == currentPage.id %}
{% set activeClass = "active" %}
{% endif %}
{% endif %}
<ul class="{{ activeClass }} {% if parent == null %}clearfix{% endif %}" data-level="{{ level }}">
{% if includeStartpage %}
{% set startseite = craft.entries.section('homepage').first() %}
<li {% if currentPage.id == startseite.id %}class="active" {% endif %}>
<a href="{{ startseite.url }}" title="{{ startseite.title }}">{{ startseite.title|raw }}</a>
</li>
{% endif %}
{% if showParentPage and parent%}
<li>
<a href="{{ parent.url }}" title="{{ parent.title }}">{{ parent.title|raw }}</a>
</li>
{% endif %}
<!-- you can leave that actually these are just the function to fetch the different entries
for the different menu types
if you have only one type just do set entries = craft.entries.section('pages').find()
-->
{% switch menuCategory %}
{% case 'mainmenu' %}
{% set entries = craft.entries.section('pages') %}
{% case 'topmenu' %}
{% set entries = craft.entries.section('pages').showInHeaderMenu('1') %}
{% case 'footermenu' %}
{% set entries = craft.entries.section('pages').showInFooterMenu('not 0') %}
{% case 'descendants' %}
{% set entries = parent.getChildren() %}
{% endswitch %}
{% for page in entries %}
<!-- macro to get the different urls for different entries...
we have sometimes links to external pages so you could use page.getUrl() as well -->
{% set url = _self.getUrl(page) %}
{% set target = _self.getTarget(page) %}
{% set title = page.title %}
{% set class = "" %}
{% switch page.type.handle %}
{% case 'internalLink' %}
{% set title = page.linkName %}
{% case 'externalLink' %}
{% set title = page.linkName %}
{% default %}
{% endswitch %}
{% if (originalPage.getUrl == url|trim and not page.hasDescendants) %}
{% set class = "active" %}
{% endif %}
{# Check if entry has descendants #}
{% if not page.hasDescendants or (menuCategory == "footermenu" or menuCategory == "topmenu") %}
{# List navigation item if entry has NO child entries #}
<li class="{{ class }}">
<a href="{{ url|trim }}" title="{{ title }}" {{ target }}>{{ title|raw }}</a>
</li>
{% elseif menuCategory == "mainmenu" or menuCategory == "descendants" %}
{# List navigation item if entry does have children #}
<li>
<a href="#" class="{{ class }}" title="{{ title }}">{{ title|raw }}</a>
{% set includeParent = (page.type.handle != 'pageWithoutContent')? true : false %}
{{ _self.menu('descendants', page, false, level+1, page, originalPage, includeParent ) }}
</li>
{% endif %}
{% endfor %}
</ul>
{% endmacro %}
Edit
You can use it with
{% import '_macros/menu.twig' as menu %}
<nav id="mainmenu" class="inline">
{{ menu.menu('mainmenu', entry, true) }}
</nav>
You can remove all the entry.getType().handle
checks. We have the entry types pageWithoutContent
so they will only appear in the menu as "placeholders" to open sub menus, but if the entry type is a page with content the entry must appear in the sub menu as well to make it clickable for mobile devices. These pages need to have an active
when they appear as "parents" but not as "children". You can see a working example of this menu here or here
nav
has very limited use and it's difficult to create flexible nested menus. If you are willing to use a macro I could provide some code