<p>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.</p>

<p>It looks a bit overwhelming at first, because we had many things to consider but it's relative easy </p>

<pre><code>&lt;!--
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
--&gt;
{% 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 %}

    &lt;ul class="{{ activeClass }} {% if parent == null %}clearfix{% endif %}" data-level="{{ level }}"&gt;
        {% if includeStartpage %}
            {% set startseite = craft.entries.section('homepage').first() %}
            &lt;li {% if currentPage.id == startseite.id %}class="active" {% endif %}&gt;
                &lt;a  href="{{ startseite.url }}" title="{{ startseite.title }}"&gt;{{ startseite.title|raw }}&lt;/a&gt;
            &lt;/li&gt;
        {% endif %}

        {% if showParentPage and parent%}
            &lt;li&gt;
                &lt;a  href="{{ parent.url }}" title="{{ parent.title }}"&gt;{{ parent.title|raw }}&lt;/a&gt;
            &lt;/li&gt;
        {% endif %}

        &lt;!-- 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()
        --&gt;
        {% 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 %}
            &lt;!-- macro to get the different urls for different entries...
            we have sometimes links to external pages so you could use page.getUrl() as well --&gt;
            {% 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 #}
                &lt;li class="{{ class }}"&gt;
                    &lt;a href="{{ url|trim }}" title="{{ title }}" {{ target }}&gt;{{ title|raw }}&lt;/a&gt;
                &lt;/li&gt;

            {% elseif menuCategory == "mainmenu" or menuCategory == "descendants" %}
                {# List navigation item if entry does have children #}
                &lt;li&gt;
                    &lt;a href="#" class="{{ class }}" title="{{ title }}"&gt;{{ title|raw }}&lt;/a&gt;
                    {% set includeParent = (page.type.handle != 'pageWithoutContent')? true : false %}
                    {{ _self.menu('descendants', page, false, level+1, page, originalPage, includeParent ) }}
                &lt;/li&gt;
            {% endif %}
        {% endfor %}
    &lt;/ul&gt;
{% endmacro %}
</code></pre>

<p><strong>Edit</strong></p>

<p>You can use it with</p>

<pre><code>{% import '_macros/menu.twig' as menu %}
&lt;nav id="mainmenu" class="inline"&gt;
    {{ menu.menu('mainmenu', entry, true) }}
&lt;/nav&gt;
</code></pre>

<p>You can remove all the <code>entry.getType().handle</code> checks. We have the entry types <code>pageWithoutContent</code> 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 <code>active</code> when they appear as "parents" but not as "children". You can see a working example of this menu <a href="http://www.baunach-allianz.de/" rel="nofollow noreferrer">here</a> or <a href="https://www.cdu-landtag.de/" rel="nofollow noreferrer">here</a></p>

CC BY-SA 3.0
2018-03-02T16:23:16.883Z
Cool thnx! Haven't tried it yet but I'll take your word for it and mark this as the answer for now.
Jalen Davenport
CC BY-SA 3.0
2018-03-02T14:58:11.007Z
2018-03-02T16:34:09.030Z
2018-03-02T16:34:09.030Z
Robin Schambach
<p>Try wrapping the <code>{% ifchildren %}</code> block with this <code>{% if page.enabled %}</code>.</p>

<p>Full example.</p>

<pre><code>{% nav page in craft.entries.section('pages') %}
&lt;li&gt;
    &lt;a href="{{ page.url }}"&gt;{{ page.title }}&lt;/a&gt;

    {% if page.enabled %}
        {% ifchildren %}
            &lt;ul&gt;{% children %}&lt;/ul&gt;
        {% endifchildren %}
    {% endif %}

&lt;/li&gt;
{% endnav %}
</code></pre>

<p>PS: I also fixed two typos in your original code.</p>

<p>EDIT:</p>

<p>Perhaps you could filter out the entries that you want, something like this:</p>

<pre><code>{% set entries = craft.entries.section('products').level(1) %}
{{ entries | length | inspect }}
{% set enabledPages = [] %}
{% for entry in entries %}
  {% if entry.enabled %}
    {% set enabledPages = enabledPages | merge([entry]) %}
    {% if entry.hasDescendants %}
      {% set enabledPages = enabledPages | merge(entry.children) %}
    {% endif %}
  {% endif %}
{% endfor %}

{# !! and then the stuff from above without the if page.enabled test #}

{% nav page in craft.entries.section('pages') %}
    &lt;li&gt;
        &lt;a href="{{ page.url }}"&gt;{{ page.title }}&lt;/a&gt;
        {% ifchildren %}
            &lt;ul&gt;{% children %}&lt;/ul&gt;
        {% endifchildren %}
    &lt;/li&gt;
{% endnav %}
</code></pre>

CC BY-SA 3.0
2018-03-02T13:51:50.307Z
thanks for the heads-up on the typos. They're not in the original code lol but I did a little bit of editing when I copy/pasted into SE. So like I mentioned in the question, surrounding any part of the `{% nav %}` contents gives me the following error: `Unexpected "ifchildren" tag (expecting closing tag for the "if" tag defined near line 53).` (this is what I get when I use the code you provided above). Any thoughts?
Jalen Davenport
CC BY-SA 3.0
2018-03-05T11:30:21.680Z
Maybe you could create a new array of entries that only contain the ones that have been enable on the 1st level. Something like this
martisj
CC BY-SA 3.0
2018-03-02T13:36:51.870Z
2018-03-05T11:44:15.607Z
2018-03-05T11:44:15.607Z
martisj
<p>So I've got a <code>{% nav %}</code> I'm trying to create with the following code:</p>

<pre><code>{% nav page in craft.entries.section('pages') %}
    &lt;li&gt;
        &lt;a href="{{ page.url }}"&gt;{{ page.title }}&lt;/a&gt;

        {% ifchildren %}
            &lt;ul&gt;{% children %}&lt;/ul&gt;
        {% endifchildren %}

    &lt;/li&gt;
{% endnav %}
</code></pre>

<p>My issue is that I've got a top-level page that has been disabled but has some enabled child/sub pages (second-level). So the code above doesn't display the disabled top-level page but it <strong>is</strong> showing all the enabled children of that disabled page. I've tried wrapping different parts of the <code>{% nav %}</code> code with a conditional but that seems to interfere with the <code>{% ifchildren %}</code> tag.</p>

<p>So my question is, is this the default Craft functionality? If so, what's the best way to solve this problem? Thanks!</p>

CC BY-SA 3.0
2018-03-02T14:30:18.270Z
I would suggest you to build a custom menu macro for that. The `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
Robin Schambach
CC BY-SA 3.0
2018-03-02T14:34:57.700Z
@RobinSchambach for sure. Add it as an answer and I'll go ahead and accept it for now ️
Jalen Davenport
<templating><navigation><children>
How do I hide children of a disabled parent in a nav?
# How do I hide children of a disabled parent in a nav?

(Asked by: username_0 on 2018-03-02)

So I've got a {% nav %} I'm trying to create with the following code:
{% nav page in craft.entries.section('pages') %}
    
        {{ page.title }}

        {% ifchildren %}
            {% children %}
        {% endifchildren %}

    
{% endnav %}

My issue is that I've got a top-level page that has been disabled but has some enabled child/sub pages (second-level). So the code above doesn't display the disabled top-level page but it is showing all the enabled children of that disabled page. I've tried wrapping different parts of the {% nav %} code with a conditional but that seems to interfere with the {% ifchildren %} tag.
So my question is, is this the default Craft functionality? If so, what's the best way to solve this problem? Thanks!

**Tags:** templating, navigation, children
> **Comments:**
> **username_1**: I would suggest you to build a custom menu macro for that. The `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  
> **username_0**: @RobinSchambach for sure. Add it as an answer and I'll go ahead and accept it for now ️  

---

## 2 answers

### Answer by username_1 on 2018-03-02. Score: 3 | Accepted answer

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 

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

    
        {% if includeStartpage %}
            {% set startseite = craft.entries.section('homepage').first() %}
            
                {{ startseite.title|raw }}
            
        {% endif %}

        {% if showParentPage and parent%}
            
                {{ parent.title|raw }}
            
        {% endif %}

        
        {% 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 %}
            
            {% 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 #}
                
                    {{ title|raw }}
                

            {% elseif menuCategory == "mainmenu" or menuCategory == "descendants" %}
                {# List navigation item if entry does have children #}
                
                    {{ title|raw }}
                    {% set includeParent = (page.type.handle != 'pageWithoutContent')? true : false %}
                    {{ _self.menu('descendants', page, false, level+1, page, originalPage, includeParent ) }}
                
            {% endif %}
        {% endfor %}
    
{% endmacro %}

Edit
You can use it with
{% import '_macros/menu.twig' as menu %}

    {{ menu.menu('mainmenu', entry, true) }}


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

> **Comments:**
> **username_0**: Cool thnx! Haven't tried it yet but I'll take your word for it and mark this as the answer for now.  

---

### Answer by username_2 on 2018-03-02. Score: 1

Try wrapping the {% ifchildren %} block with this {% if page.enabled %}.
Full example.
{% nav page in craft.entries.section('pages') %}

    {{ page.title }}

    {% if page.enabled %}
        {% ifchildren %}
            {% children %}
        {% endifchildren %}
    {% endif %}


{% endnav %}

PS: I also fixed two typos in your original code.
EDIT:
Perhaps you could filter out the entries that you want, something like this:
{% set entries = craft.entries.section('products').level(1) %}
{{ entries | length | inspect }}
{% set enabledPages = [] %}
{% for entry in entries %}
  {% if entry.enabled %}
    {% set enabledPages = enabledPages | merge([entry]) %}
    {% if entry.hasDescendants %}
      {% set enabledPages = enabledPages | merge(entry.children) %}
    {% endif %}
  {% endif %}
{% endfor %}

{# !! and then the stuff from above without the if page.enabled test #}

{% nav page in craft.entries.section('pages') %}
    
        {{ page.title }}
        {% ifchildren %}
            {% children %}
        {% endifchildren %}
    
{% endnav %}

> **Comments:**
> **username_0**: thanks for the heads-up on the typos. They're not in the original code lol but I did a little bit of editing when I copy/pasted into SE. So like I mentioned in the question, surrounding any part of the `{% nav %}` contents gives me the following error: `Unexpected "ifchildren" tag (expecting closing tag for the "if" tag defined near line 53).` (this is what I get when I use the code you provided above). Any thoughts?  
> **username_2**: Maybe you could create a new array of entries that only contain the ones that have been enable on the 1st level. Something like this  

---

