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

Consider changing the precedence of title sources #3532

Open
ofek opened this issue Dec 30, 2023 · 32 comments · May be fixed by #3533
Open

Consider changing the precedence of title sources #3532

ofek opened this issue Dec 30, 2023 · 32 comments · May be fixed by #3533
Labels

Comments

@ofek
Copy link
Contributor

ofek commented Dec 30, 2023

Specifically, on this page https://www.mkdocs.org/user-guide/writing-your-docs/#meta-data I would prefer that the level 1 headers take priority over the navigation name, or an option to do so.

I'm realizing that deriving the title from the navigation sidebar does not provide a good user experience and I would like to avoid having to add meta-content to every page. I will use a real example: https://hatch.pypa.io/1.9/config/static-analysis/

The sidebar already represents clearly defined sections and in this case the entire sidebar relates to config so it would be very verbose to add the word "configuration" to every name.

Here is the full(ish) picture showing the desired title as the level 1 header:

image

A consequence is that when you scroll down with Material for MkDocs the title on top is now no longer specific:

image

As well as the social card that shows up when you post a link to a page in Slack or Twitter or Discord:

slack-imgs

@ofek
Copy link
Contributor Author

ofek commented Dec 30, 2023

Maybe there is a way to achieve this immediately with a hook?

@oprypin
Copy link
Contributor

oprypin commented Dec 30, 2023

I think this is a behavior of mkdocs-material, or I don't understand what you're describing.

@oprypin
Copy link
Contributor

oprypin commented Dec 30, 2023

Aha no, I see. Although both of the shown examples of how the page title is displayed are unique to mkdocs-material, the source of that title is deduced by MkDocs. It's presumably also put into the <title> tag which would be a generic example?

@oprypin
Copy link
Contributor

oprypin commented Dec 30, 2023

Yeah it's a good point. MkDocs just expects you to use the same title in the navigation and in the first heading. A page doesn't have multiple kinds of titles. This feature would be tough to introduce conceptually and would have to be an awkward new config entry 😞

@oprypin
Copy link
Contributor

oprypin commented Dec 30, 2023

Actually all themes at the moment explicitly use the same title attribute for both the page title and the nav entry. So in a simplistic view, this isn't even possible to change by changing something only in MkDocs.

<title>{% if page and page.title and not page.is_homepage %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>

<a href="{{ nav_item.url|url }}" class="nav-link">{{ nav_item.title }}</a>

My only idea is to add a new attribute and then themes could use it. There actually already is such an attribute but it's private -

self._title_from_render = extract_title_ext.title

@oprypin oprypin linked a pull request Dec 30, 2023 that will close this issue
@ofek
Copy link
Contributor Author

ofek commented Dec 30, 2023

cc @squidfunk for visibility

@ofek
Copy link
Contributor Author

ofek commented Dec 30, 2023

Actually all themes at the moment explicitly use the same title attribute for both the page title and the nav entry.

In Material for MkDocs if I set the following then the title is in fact updated appropriately without changing the text in the sidebar: https://squidfunk.github.io/mkdocs-material/reference/#setting-the-page-title

Is there some way I can artificially set this metadata attribute in a hook based on the level 1 header?

@squidfunk
Copy link
Sponsor Contributor

Title handling is broken since MkDocs 1.5 (see #3357). There are some instances where markup ends up in Page.title (see linked issue). Should Page.meta.title be allowed to contain markup? Plugins that rely on reading page titles in on_page_markdown or on_page_content might end up with inconsistent results, if Page.title is changed after reading the Markdown, but I guess this is no more worse than the current situation. Before anything is changed on title handling, it should be solidly spec'd, because there are several cases that currently lead to undefined behavior.

My 2 cents.

@ofek
Copy link
Contributor Author

ofek commented Jan 21, 2024

pypa/hatch#1216

I just tried setting the front matter via a hook but it looks like at that point the metadata is already stripped out and processed. Is there a way to set the title based on the h1 via a hook?

@ofek
Copy link
Contributor Author

ofek commented Jan 28, 2024

@oprypin Do you know of a way?

@ofek
Copy link
Contributor Author

ofek commented Feb 1, 2024

I tried looking into the code base but I still am not sure unfortunately.

@oprypin
Copy link
Contributor

oprypin commented Feb 1, 2024

@ofek It is extremely convoluted to bypass the title machinery right now in the way that you want, which is why I wasn't suggesting anything. Could you wait for further developments regarding titles

@ofek
Copy link
Contributor Author

ofek commented Feb 1, 2024

Sure I'm fine with waiting sorry to bother! Although, outside of titles is there any way to change front matter via a hook?

@oprypin
Copy link
Contributor

oprypin commented Feb 3, 2024

Should Page.meta.title be allowed to contain markup

No but it always was allowed to contain markup 😞 and seems like it will stay this way. You've been saying it like MkDocs 1.5 changed this but actually it didn't change anything for Page.meta.title. Indeed, see #3357 (comment)

@oprypin
Copy link
Contributor

oprypin commented Feb 3, 2024

For this change itself, I am interested to know if you'd be happy to apply it when the new attribute is available, @squidfunk .

https://github.com/squidfunk/mkdocs-material/blob/bcad9cecd18b47409988ebb0aa69bea6a7edd70c/src/templates/base.html#L91-L97
to become

      {% if page.title and not page.is_homepage %}
        <title>{{ page.content_title | striptags }} - {{ config.site_name }}</title>
      {% else %}
        <title>{{ config.site_name }}</title>
      {% endif %}

https://github.com/squidfunk/mkdocs-material/blob/bcad9cecd18b47409988ebb0aa69bea6a7edd70c/material/templates/partials/header.html#L28-L32
to become

            {{ page.content_title }}

You've added this special case to prioritize as follows:

  1. meta['title']
  2. title from mkdocs.yml nav
  3. title from content

But instead this would now prioritize as follows:

  1. meta['title']
  2. title from content
  3. title from mkdocs.yml nav

Which would make more sense to both me and @ofek

@squidfunk
Copy link
Sponsor Contributor

squidfunk commented Feb 4, 2024

Honestly, I'm having a really hard time committing to anything with "yes" or "no" right now, because there are so many changes related to title handling in the making that I'm not able to keep up. What you're proposing sounds good, but that is only a guess. There might be side effects that break things. If this gets merged, IMHO, the maintainers of MkDocs might consider a prerelease to give plugin and theme authors enough time to test and adjust.

@oprypin oprypin added this to the 1.6.0 milestone Feb 4, 2024
@waylan
Copy link
Member

waylan commented Feb 4, 2024

The existing prioritization is based on the idea that explicit trumps implicit. If a user explicitly defines a title for a page (in nav or meta-data), then that title is used. However, if the user does not explicitly define a title, then get the implied title from the first <h1> of the page content, and if that doesn't exist, then from the file name. Personally, no other order makes logical sense to me. Why would we ignore the explicitly defined title in the nav and use the implicit title in the body content of the page?

That said, there have been many requests over the years to have the nav title only be the label in the site navigation, but not be the page title. However, I have always rejected that as I am not aware of a graceful way to make that change for the many users who have all of their page titles defined in their nav. Personally, if I have a title defined in my nav, under no circumstances do I want a future update to MkDocs to suddenly start using the <h1> of the page as the page title.

I suppose an additional config option could be added which basically causes nav titles to be ignored. But then why is the user defining them? As previously noted, the nav is not separate from the pages collection and so there is no second nav-only-title. Unless the config setting was added at the same time as some new nav object which was separate from the page objects.

@oprypin
Copy link
Contributor

oprypin commented Feb 4, 2024

Thanks for the feedback. I still believe that there's no way that the current behavior makes more sense than the proposed behavior, but with this feedback in mind, it will surely break at least some users' expectation from pre-existing behavior. Then perhaps my change should stop at just adding the new attribute, without changing built-in themes.

@oprypin
Copy link
Contributor

oprypin commented Feb 4, 2024

And I do think that at the very least what mkdocs-material currently does would make a lot of sense for all themes. Namely,

<title>{{ page.meta.title or page.title }}</title>

because with similar logic, why on earth would the user specify the meta title if it's impossible for it to be used if the site specifies titles in the nav config.
I think this should be recommended and built-in themes should be changed to this

@ofek
Copy link
Contributor Author

ofek commented Feb 4, 2024

I suppose an additional config option could be added which basically causes nav titles to be ignored. But then why is the user defining them?

Please see the pictures I posted in the OP. It is desirable to have the actual title be more verbose which is undesirable in the short link one would click on the side.

@oprypin
Copy link
Contributor

oprypin commented Feb 4, 2024

Simply adding the new attribute will enable mkdocs-material to change the source of this floating pop-out title element. (Which is a totally unique concept in this theme.) I think that will be uncontroversial.

The question whether it will also make sense change the source of the <title> is not so simple apparently.

@pawamoy
Copy link
Sponsor Contributor

pawamoy commented Feb 4, 2024

OK, I had to re-read a few times to make sure I understand. If the proposal is the following, then I'm -0:

  • titles specified in mkdocs.yml's nav keep being used as labels for the navigation (left sidebar in Material for MkDocs)
  • HTML <title> for each page is now populated from the H1 heading of the page, not the title specified in mkdocs.yml's nav
  • in cases where this is not desirable, it is still possible to override the HTML <title> with the front-matter titlemetadata

In some pages of mine, I have the opposite case of @ofek's: Markdown title is short, nav title is longer and more descriptive, so I want the nav title to be used as HTML title (current behavior). With this proposal implemented, I can still achieve that by copying the nav title in the front-matter title metadata, so that's not all bad. IMO at this point, it doesn't really matter which of the Markdown or nav title is used for the HTML title: some users will want the first, others the second (I myself use both 🤷). I'm not sure which one makes the most sense. Since not all users will be satisfied, I think I'd favor not breaking current behavior? Maybe some usage statistics of front-matter title metadata would give us some pointers?

@pawamoy
Copy link
Sponsor Contributor

pawamoy commented Feb 4, 2024

(I'm therefore also totally open to a new option for giving precedence to nav or Markdown titles)

@oprypin
Copy link
Contributor

oprypin commented Feb 5, 2024

Alright, so there will be no change to how <title> is determined by default.
#3533 will only keep the addition of the new attribute but not use or recommend it for anything.

This can enable more flexibility in hooks (example pypa/hatch#1239) and new possibilities for themes with advanced features (example #3532 (comment))

@oprypin
Copy link
Contributor

oprypin commented Feb 5, 2024

Or well actually I am still interested to bump the priority of page.meta.title over the nav title , like mkdocs-material already does
(#3532 (comment))
But definitely not bumping the priority of the H1 title

@waylan
Copy link
Member

waylan commented Feb 5, 2024

why on earth would the user specify the meta title if it's impossible for it to be used if the site specifies titles in the nav config

Some more background. MkDocs didn't always to support defining page titles in the meta-data. And so if a user wanted a page title to be something other than the the <h1>, then they needed to use the nav. However, understandably, users did not like editing page attributes somewhere other than in the page file itself. So we added the meta-data option for those users.

So nav was the oldest and only option to begin with. (with filename as a fallback) Those users need to continue to be supported. Each additional option was built later, so they all have lower priority. And as explicit takes precedence over implicit, then we get nav, meta-data, content, filename as the only order we can support without breaking existing users sites.

But yes, a theme (or a custom template provided by a user) could conceivably check page.meta.title and use that instead of page.title. However, that only makes sense when page.title comes from the nav. Because in any other scenario, page.meta.title and page.title will be the same. That said, if a theme used some different meta-data key (like maybe nav-title), then anything is possible (including <title>{{ page.meta.nav-title or page.title }}</title>. In fact, this doesn't even need any changes to MkDocs for the user to do. A theme could build this in or even use a theme config option to optionally enable it. Or a user could define their own custom template block to override the relevant block of the theme they use.

@ofek
Copy link
Contributor Author

ofek commented Feb 5, 2024

In some pages of mine, I have the opposite case of @ofek's: Markdown title is short, nav title is longer and more descriptive, so I want the nav title to be used as HTML title (current behavior).

@pawamoy Can you please share an example? I think in the vast majority of cases users would benefit from the default sourced from the h1. I understand that probably won't happen, I'm just saying.

@pawamoy
Copy link
Sponsor Contributor

pawamoy commented Feb 5, 2024

And you might be right! It would be interesting to look at current usage of meta+nav titles (only working with mkdocs-material IIUC) compared to nav+markdown titles, to see which use is the most common. I'm going to bed but I'll share an example tomorrow :)

@oprypin
Copy link
Contributor

oprypin commented Mar 16, 2024

Alright, so there will be no change to how <title> is determined by default.
#3533 will only keep the addition of the new attribute but not use or recommend it for anything.

This can enable more flexibility in hooks (example pypa/hatch#1239) and new possibilities for themes with advanced features (example #3532 (comment))

@tomchristie
Copy link
Member

tomchristie commented Apr 15, 2024

I would prefer that the level 1 headers take priority over the navigation name

We can't make a switch like that, no. It'd break other users expectations. Echoing @waylan's comment above... "if I have a title defined in my nav, under no circumstances do I want a future update to MkDocs to suddenly start using the <h1> of the page as the page title."

or an option to do so

We should avoid configuration options where possible.
Theming options, great. Configuration options, bad.

I'd suggest that if there is an approach to resolving this, then it should be through theming and passing sufficient nav + toc context to the theme.

There's also a design flaw that's been pointed to...

The existing prioritization is based on the idea that explicit trumps implicit. If a user explicitly defines a title for a page (in nav or meta-data), then that title is used. However, if the user does not explicitly define a title, then get the implied title from the first <h1> of the page content, and if that doesn't exist, then from the file name.

That's something that I think? goes way back to early versions of MkDocs. A much neater approach would be to just be explicit. A nav config that always includes titles would be how I'd approach this if I was looking at a redesign. The toc structure could also be passed as context, and the decision around which to us would be a theming issue.

@squidfunk
Copy link
Sponsor Contributor

That's something that I think? goes way back to early versions of MkDocs. A much neater approach would be to just be explicit. A nav config that always includes titles would be how I'd approach this if I was looking at a redesign. The toc structure could also be passed as context, and the decision around which to us would be a theming issue.

I just had a talk with @pawamoy on another backlog grooming call that we did today on this very topic, after we didn't have enough time yesterday. It's important to know that there are many users that just throw a folder of Markdown files at MkDocs without specifying an explicit structure, which is an awesome way to get started quickly.

There are also several plugins that allow to manage explicit navigation auto-magically outside of mkdocs.yml. Thus, keeping this functionality, IMHO, is absolutely essential to provide a great out-of-the box experience ☺️ Also note that it's not primarily a theming issue, as plugins also need to know titles of pages, e.g. the search plugin.

All of that just from the top of my head – deeper evaluation required.

@tomchristie
Copy link
Member

It's important to know that there are many users that just throw a folder of Markdown files at MkDocs without specifying an explicit structure

Related #3356

@pawamoy pawamoy added the Titles label Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants