Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

Support

How to separate 'normal' child pages from modular children?

Started by Harald 6 years ago · 3 replies · 744 views
6 years ago

HI,

I'm just beginning to learn Grav because I need to port several websites from a dying CMS.

For a drop-down menu I use the approach from the 'Photographer' theme as explained in 'Loop to add children pages as dropdown'.
To detect children, it uses:

TWIG
{% if p.children.count > 0 %}
                    <ul>
                        {{ _self.loop(p) }}
                    </ul>
                {% endif %}

In my setup I use modular pages and 'normal' child pages.
The filter above does take both of them as children, but in my menu I only need the latter ones of course. In the menu on the page the modular children do not appear, but in the source there are empty <ul> </ul> tags.
How can I avoid this?

Edit: code corrected
bigboy

last edited 07/14/20 by Harald
6 years ago

Hoping to bring some more clarity to the question, I have added the file structure, some more explanation and the headers of relevant pages.

File structure:

TXT
pages
├── 01.home
│   └── default.md
├── 02.eigenschaften      (*1 has "wrong" children)
│   ├── modular.md
│   ├── _anwendung        (*1)
│   │   └── text.md
│   ├── (some more modules)
│   └── _fazit            (*1)
│       └── text.md
├── 03.produkte          (*2 has "real" children)
│   ├── default.md
│   │
│   ├── 04.implantate    (*2, has "wrong" children *1)
│   │   ├── modular.md
│   │   ├── _implantat1  (*1)
│   │   │   └── text.md
│   │   ├── (some more modules)
│   │   └── _implantat4  (*1)
│   │       └── text.md
│   │
│   └── 05.werkzeuge     (*2, has "wrong" children *1)
│       ├── modular.md
│       ├── _werkzeug1   (*1)
│       │   └── text.md
│       ├── (some more modules)
│       └── _werkzeug3   (*1)
│           └── text.md
├── 04.kontakt
│   └── form.md
├── 05.impressum             (*1 has "wrong" children)
│   ├── modular-accodion.md
│   ├── _inhalte             (*1)
│   │   └── accordion.md
│   ├── (some more modules)
│   └── _werbe-mails         (*1)
│       └── accordion.md
└── 06.datenschutz           (*1 has "wrong" children)
    ├── modular-accodion.md
    ├── _analyse-tool        (*1)
    │   └── accordion.md
    ├── (some more modules)
    └── _plugins-tools-maps  (*1)
        └── accordion.md

1 - these are modules of a modular page and should not appear in the dropdown menu and the modular page should not get param 'submenu'.
2 - these are children of a page and shall appear in the dropdown menu as 2nd level; the parent page shall get the param 'submenu'.

Both of them are equally considered to be children of their parent by "p.children.count".
The "real" ones are shown in the menu in 2nd level with their menu title, the "wrong" ones are not, but their parent is marked as having a submenu.

Two examples of headers:

  • for 03.produkte:
    YAML
    title: Produkte
    menu: Produkte
    
  • for 04.implantate:
    YAML
    title: Implantate
    content:
    items: '@self.modular'
    order:
      by: default
      dir: asc
      custom:
        - _implantat1
        - _implantat2
        - _implantat3
        - _implantat4
    menu: Implantate
    

    bigboy

last edited 07/21/20 by pamtbaau
6 years ago

@bigboy, Ah, thanks for the updated information. I do get a better picture of the overall situation now.

I think the issue is related in the Twig code. You are looping through all children, while you only want the visible children.
If you've only taken the above snippet from the Photographer theme, you may have missed the test {% if p.visible %} in its navigation template.

Try the following:

TWIG
{% if p.children.visible.count > 0 %}
  <ul>
    {{ _self.loop(p) }}
  </ul>
{% endif %}

If have create a little example using a default Grav installation using Quark.

TXT
pages
├── 01.home
│   └── default.md
├── 02.typography
│   └── default.md
└── 03.modular1
    ├── _module1
    │   └── text.md
    ├── _module2
    │   └── text.md
    └── modular.md

Using p.children the menu becomes:

image|305x118
Does the above resemble your menu?

Using p.children.visible the menu becomes:

image|298x40

last edited 07/21/20 by pamtbaau
6 years ago

@pamtbaau:
If you’ve only taken the above snippet from the Photographer theme, you may have missed the test {% if p.visible %} in its navigation template.

No, that test is present as in the Photographer theme.
Here is the full relevant code from the navigation.html.twig partial:

TWIG
{% macro loop(page) %}
  {% for p in page.children %}
    {% if p.visible %}
      {% set current_page = (p.active or p.activeChild) ? 'active' : '' %}
      {% set menu_level = (p.children.count > 0) ? 'submenu ' : '' %}
      <li class="{{ menu_level }}{{ current_page }}">
        {% if current_page == 'active' %}
          <a href="{{ p.url }}">{{ p.menu }}</a><span class="sr-only">&#160;(aktiv)</span>
        {% else %}
          <a href="{{ p.url }}">{{ p.menu }}</a>
        {% endif %}
        {% if menu_level == 'submenu ' %}
          <ul>
            {{ _self.loop(p) }}
          </ul>
        {% endif %}
      </li>
    {% endif %}
  {% endfor %}
{% endmacro %}

I still don't understand why that is not working as expected, i.e. every menu item is marked as parent, despite the set visible filter.
Anyway, if I follow your advice and replace the 5th line as follows

TWIG
 {% set menu_level = (p.children.visible.count) ? 'submenu ' : '' %}

everything is OK! Great!
This allows me to use a pure HTML/CSS multilevel drop-down menu (no JavaScript) in my websites.
Thank you for this "magic"(?) tip.

bigboy

last edited 07/21/20 by Harald

Suggested topics

Topic Participants Replies Views Activity
Support · by Thomas, 1 week ago
2 60 15 hours ago
Support · by Anna, 3 days ago
2 66 18 hours ago
Support · by Justin Young, 19 hours ago
1 33 19 hours ago
Support · by Duc , 1 week ago
2 69 6 days ago
Support · by Colin Hume, 1 week ago
2 61 6 days ago