Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for sections with pages #1008

Closed
wilhelmer opened this issue Feb 26, 2019 · 14 comments
Closed

Add support for sections with pages #1008

wilhelmer opened this issue Feb 26, 2019 · 14 comments

Comments

@wilhelmer
Copy link
Contributor

Currently, a parent nav item (one which contains children) cannot have a page attached to it, as stated in the MkDocs documentation.

This means that in the following navigation structure, I can't link from other topics to the general "Products" page, which is inconvenient:

nav:
    - Home: index.md
    - Products:
        - Product A: product-a.md
        - Product B: product-a.md
    - Support: support.md

However, as @waylan pointed out in this comment, this could be overriden by a template.

It would be great if material supported waylan's suggested implementation.

@squidfunk
Copy link
Owner

I currently don't have the time to evaluate this request in-depth, but it's most probably orthogonal to the current implementation. In theory it COULD work, if and only if the existence of such a section page is detectable from the Jinja template, so the rendering can be made accordingly. However, I would only consider implementing it, if it's fully backward-compatible to the "normal" way because I believe this syntax is a) counter-intuitive (never thought this was possible) and b) has the potential to break a lot downstream.

To sum up: this needs further evaluation which I'm not able to deliver at the moment. If you or somebody else feels diving into this topic is worth the time, feel free to do so and share your findings here. I believe it's probably not worth.

@waylan
Copy link
Contributor

waylan commented Feb 26, 2019

For anyone who is interested in working on a solution for this, I provided some more details about how I envision this working here.

@wilhelmer
Copy link
Contributor Author

My approach is probably super bad (I'm not a developer), but maybe it helps in finding a good solution:

Add a theme config option:

theme:
    section_page_name: index

Then define a nav like this:

nav:
    - Home: index.md
    - Products:
        - index: products.md
        - Product A: product-a.md
        - Product B: product-a.md
    - Support: support.md

In nav-item.html, change

<label class="md-nav__link" for="{{ path }}">
  {{ nav_item.title }}
</label>

to

<label class="md-nav__link" for="{{ path }}">
  {% if nav_item.children[0].title == config.theme.section_page_name %}
  <a href="{{ nav_item.children[0].url|url }}" title="{{ nav_item.title }}">
    {{ nav_item.title }}
  </a>
  {% else %} 
    {{ nav_item.title }}
  {% endif %}
</label>

This sets the url of the parent entry to the url of the first child, but only if its title matches the section_page_name.

Now we have to exclude the section_page_name entry from the navigation:

Change

{% elif nav_item == page %}
...
{% else %}
...
{% endif %}

to

{% elif nav_item.title != config.theme.section_page_name %}
  {% if nav_item == page %}
   ...
   {% else %}
   ...
   {% endif %}
{% endif %}

@squidfunk
Copy link
Owner

squidfunk commented Feb 26, 2019

Thanks @waylan, I didn't know that there's an .is_index member on a page/child. That would make distinction possible.

But: Material uses sections to group content and collapses them in the navigation on the left side (or in the sidebar on mobile), ergo it is assumed that there's no content behind a section and it is solely used for grouping. A change like this would require to rethink the grouping semantics within the menus - i.e. what to do with sections that have content, as they now cannot be used as a toggle to collapse or expand further pages but actually lead to a page.

@wilhelmer
Copy link
Contributor Author

wilhelmer commented Feb 26, 2019

Clicking on a section with a page opens the section page + expands the nav. Works perfectly with my solution. Even with tabs: true.

@squidfunk
Copy link
Owner

squidfunk commented Feb 26, 2019

This will effectively kill mobile navigation - it's actually not that easy. If you can come up with a concept that works in all configurations and doesn't change any current behavior, I'm happy to discuss.

@wilhelmer
Copy link
Contributor Author

On mobile, the section page opens and the nav panel closes.

If the section page provides links to all subpages, e.g., the "Product" page gives a short overview over the product line and then provides links to Product A, Product B and so on, that's perfectly fine for me.
Also, the user can re-open the navigation and continue from there.

It's not perfect, but I wouldn't exactly call that "kill" navigation.

Anyway, I can understand if you don't want to implement this as a standard feature. I'm happy to keep my theme extension for my own needs.

@waylan
Copy link
Contributor

waylan commented Feb 26, 2019

A change like this would require to rethink the grouping semantics within the menus

Which is why the builtin themes don't support this. I expect that to properly support this someone will need to create a new theme which incorporates this feature from the beginning as a core feature. I do not expect any existing themes to easily wedge this in without major changes to how navigation works.

@squidfunk
Copy link
Owner

Also, the user can re-open the navigation and continue from there.

IMHO this is rather bad UX.

It's not perfect, but I wouldn't exactly call that "kill" navigation.

Yes, this kills easy navigation, as it induces a full page reload which can be slow on some networks and interrupts the flow if you just want to expand the section.

Anyway, I can understand if you don't want to implement this as a standard feature. I'm happy to keep my theme extension for my own needs.

Thanks, I think I made my point. When evaluating such a change, we have to think of all possible use cases how users currently use this theme, as we try to break as little as possible with new features or updates. This is also why this theme is so popular: after three years it is in fact very stable and mature.

Which is why the builtin themes don't support this. I expect that to properly support this someone will need to create a new theme which incorporates this feature from the beginning as a core feature. I do not expect any existing themes to easily wedge this in without major changes to how navigation works.

Jep, this is exactly what I'm thinking. If Material would adapt this change, we would need to get rid of expandable and collapsible sections and rethink mobile navigation which most of its users see as a huge gain. It doesn't matter how you do it, there's always something that is orthogonal that users want. The next question will be: could this be implemented as a feature flag? Well yeah, it could. But the changes would be too deep to make it a reasonable option for the code base as it would increase the cost of maintenance by a huge margin.

Closing this issue for the stated reasons.

@wilhelmer
Copy link
Contributor Author

wilhelmer commented Feb 26, 2019

Another option would be to implement section pages as hidden first-childs in the nav. This means nav behaviour remains unchanged, but links to the section are possible. The link opens, e.g., the "Products" page with the "Products" section correctly expanded in the nav. However, there's no way to access the "Product" page from the nav, only via links or search, which is bad UX all over again.

So you're right, in the end, it's a UX decision. If I need links to sections (and this is the only reason why I want this feature!), I can either:

a) stick with the current implementation and double nav entries:

nav:
    - Home: index.md
    - Products:
        - Products: products.md
        - Product A: product-a.md
        - Product B: product-a.md
    - Support: support.md

--> bad UX in the nav (mobile + desktop)

b) stick with the current implementation and put all product documentation in one topic:

nav:
    - Home: index.md
    - Products: products.md
    - Support: support.md

--> bad UX in the topic if it becomes too long (we have 200+ products)

c) change the implementation as suggested in my comment above
--> bad UX in the mobile nav

d) change the implementation as suggested at the beginning of this post
--> bad UX in the site structure

I'll ask our UX team which they prefer.

@squidfunk
Copy link
Owner

squidfunk commented Feb 26, 2019

Haha that's the point. Good UX is very hard ;-) Personally I think that collapsibility of sections (especially on mobile) outweighs the need to put your content in a separate page (coming first) in your section. Otherwise mobile navigation might be a lot of scrolling, which can be quite A LOT for huge documentation projects. I currently solve this problem by naming the first page within a section "Overview" or something similar.

It's always a trade-off, no matter which way you look.

EDIT: Also, note that we would need to implement this as an optional thing, because making it mandatory would mean that there will always need to be an index page. Some people might argue that they don't want that, because content is mutually exclusive aaaaand we're back to square one. However, making it optional would only lead to more confusion. I think we should just leave it as it is. If one wants to change it, theme extension is always a possibility.

@wilhelmer
Copy link
Contributor Author

wilhelmer commented Feb 27, 2019

Personally I think that collapsibility of sections (especially on mobile) outweighs the need to put your content in a separate page (coming first) in your section.

Typically, yes. But our doc site has a super uncommonly low amount of mobile users (around 1.2%), mainly because it's usually accessed from a desktop app. So we might think different about that. It always depends.

Anyway, thanks for the insight and the discussion!

@rei-vilo
Copy link

rei-vilo commented Nov 2, 2020

@wilhelmer Thank you for sharing the nice solution.

However, the section_page_name=index was added as <h1>index</h1> on top of the index page.

To prevent that, I added a minor modification to head.html.

Change

                {% if not "\x3ch1" in page.content %}
                <h1>{{ page.title | default(config.site_name, true)}}</h1>
                {% endif %}

for

                {% if page.title != config.theme.section_page_name %}
                {% if not "\x3ch1" in page.content %}
                <h1>{{ page.title | default(config.site_name, true)}}</h1>
                {% endif %}
                {% endif %}

@oprypin
Copy link
Contributor

oprypin commented Nov 22, 2020

I'm continuing discussion (in the context of a particular solution) here:
#2060

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants