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

Building hidden pages #699

Closed
jhamman opened this issue Jul 27, 2015 · 53 comments
Closed

Building hidden pages #699

jhamman opened this issue Jul 27, 2015 · 53 comments
Milestone

Comments

@jhamman
Copy link

jhamman commented Jul 27, 2015

Is it possible to tell mkdocs to build pages but not have them show up in the side bar? If it is possible, an example of how to do this in the documentation would be great.

I asked this question here as well: https://groups.google.com/forum/#!topic/mkdocs/ILW9-SIdERs

@keelii
Copy link

keelii commented Jul 27, 2015

I have the same question
mkdocs only build specified .md files in yml. Sometimes i use relative path to reference md file, but it not working for me .

if there is a glob pattern to set, It would be better ^!^ :

mdFiles: docs/*/*.md

@waylan
Copy link
Member

waylan commented Jul 27, 2015

No this is not possible as this time. I am not aware that it is on the road-map either, although I am not the one to make such a decision. I would suggest that if such a feature was to be implemented, it would use the page meta-data to define a page as "hidden" (perhaps by adding a hidden: true key-value pair to the meta-data for the page). Then, when building the nav, it would simply be skipped.

@jhamman
Copy link
Author

jhamman commented Jul 27, 2015

Thanks @waylan - Good to know.

Any thoughts on how difficult this feature would be to add? The hidden: true api is exactly what I was envisioning.

@tomchristie tomchristie mentioned this issue Jul 27, 2015
15 tasks
@robodude666
Copy link

I've ran across this same exact issue a few weeks ago, and adopted the same method that Docker used for their docs (they recently adopted Hugo):

  • Set the Page Title in the mkdocs.yml file to a special value (they used HIDDEN).
  • Update the Template to not include a pages with the above special value.

It feels very hacky, but it's working well enough for me right now. The docs base I'm maintaining is far smaller than Docker's so it's OK for now. I can imagine if you have a larger documentation base it might get annoying to maintain.

@waylan From trying to figure out how to get around this limitation, and reading older issues people opened on this topic it doesn't seem to be something that plans to be supported by mkdocs; and I would agree. mkdocs is intended to be used for simple documentation. Having dozens of hidden pages to be used for links only is a step above simple. Personally, I'd rather see this handled via a extension once API support is added.

@waylan
Copy link
Member

waylan commented Jul 29, 2015

According to a recent edit to the first comment on #689 this is addressed by the work there. That said, it is not clear to me how or when that work will be merged in.

In any event, I agree that this seems more like a feature for a plugin API.

@jhamman
Copy link
Author

jhamman commented Jul 29, 2015

Thanks for the input @robodude666 and @waylan. I went ahead and modified the read-the-docs theme to exclude nav items == 'hidden'. That seems to be working locally and on read-the-docs.

This solution came from @martinzugnoni and works like a charm, albeit a bit hackish...

This is the original "base.html" file:
https://github.com/mkdocs/mkdocs/blob/master/mkdocs/themes/readthedocs/base.html

mkdocs.yml

# Pages not available to end users
- 'hidden': 'internal_endpoints.md'

base.html

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
        <ul class="current">
          {% for nav_item in nav %}
            {% if nav_item.title != "hidden" %}               <=== this is the important line
              <li>{% include "toc.html" %}<li>
            {% endif %}
          {% endfor %}
        </ul>
      </div>

Given that this was pretty easy to implement, and has nothing to do with the complexity of the site, I would still like to see this become part of the larger package.

@d0ugal
Copy link
Member

d0ugal commented Jul 30, 2015

Neat, good to see that you found a work around for this. I would like to see this work with the Markdown metadata. For example, you might add "hidden: true" to the top of the file and then it will be excluded from the nav. I am not sure how #689 is looking to add this. @tomchristie?

@tomchristie
Copy link
Contributor

Rather than having to include them in the nav with 'hidden' it'd make more sense to just build all .md pages irrespective of if they're in 'pages' or not.

I am not sure how #689 is looking to add this

At the moment that'd build all md files, and warn if any of them are not in pages. For this behavior we'd simply want to turn that warning off.

@robodude666
Copy link

@tomchristie If pages is being used by a project I'd rather see mkdocs warn when a page is built but not in pages, and then add the ability to list only the filename/globs w/o a name.

For example:

pages:
- 'Introduction': 'index.md'
- 'User Guide': 'user-guide.md'
- 'About': 'about.md'
- hidden_file.md
- hidden/folder/*.md
- extension/generated/apis/*.md

This makes it explicit that these files are intended to be hidden, as no title is given to them (title can be extracted from filename/metadata in these cases).

It'll also help catch cases where the author or contributor creates a new file but forgets to update pages. This way they'll get a warning, which they can explicitly silence by adding it to the pages list.

It also makes it possible for extensions to generate pages that will be included, though albeit extensions would probably have access to modify the pages config...

@waylan
Copy link
Member

waylan commented Aug 3, 2015

This makes it explicit that these files are intended to be hidden, as no title is given to them (title can be extracted from filename/metadata in these cases).

My preference would be to always define the Title in the meta-data and never in the config. But according to the above proposal, that would make all my pages "hidden" which is not what I want.

All "hidden" means is that the page is excluded from the nav menu. Interestingly, if no pages config is provided, all pages are auto-discovered and included in the nav menu. All the pages config gives you is a clear way to define order and nesting of the nav menu (I see the ability to define a title as a convenient side effect). It would follow quite naturally then, that any pages not listed in the pages config would then not be listed in the nav menu. As #689 gives us this already (albeit with a warning), I don't see much room for improvement.

@robodude666
Copy link

My preference would be to always define the Title in the meta-data and never in the config.

I would agree with you, as I don't personally like my recommendation of excluding the title; it was just a simply example to illustrate explicitly hiding pages without having to add a whole bunch of new config options. If we would rather have a boolean flag in the metadata of a page, that would be fine too.

As #689 gives us this already (albeit with a warning), I don't see much room for improvement.

The improvement I'm suggesting is to only give warnings for pages that weren't explicitly hidden. If I have 100 API docs that I'm trying to hide from the navigation I don't want to see 100 warnings when I build my docs. That will make the warnings meaningless if I'm always going to ignore them as it makes it very easy for an important warning to go unnoticed.

@waylan
Copy link
Member

waylan commented Aug 3, 2015

I don't want to see 100 warnings when I build my docs.

Right, and as @tomchristie stated, those warnings should be able to be turned off. I assumed that that was clear and didn't restate it. Sounds like we are on the same page here.

@robodude666
Copy link

I'm trying to point out that they should only be turned off for specific pages, not all. If I mark 5 pages as hidden, and create a new *.md file I should get 1 warning. If that's understood then I'm okay 😄.

@dmehra
Copy link

dmehra commented Nov 18, 2015

I found the same need to hide pages from the sidebar nav, as our docs have ~200 pages, and we don't want all of them present in the sidebar menu (if collapsible nav were available per #588, that may remove the need for hiding, or perhaps still not).

What I ended up doing (in a custom theme override of toc.html) is this, inspired by comment #699 (comment) above, but replacing the word hidden with underscores ________ so it's easy to see in my mkdocs.yml which pages are hidden, it looks like this:

pages:
- Concepts:
   - 'Overview': 'concepts/overview.md'
   - '________': 'concepts/quick_ref.md'
   - '________': 'concepts/hello_world.md'
- Modules:
  - 'String': 'modules/string.md'
  - '________': 'modules/string_intro.md'

This is the salient part of my toc.html:

  {% if nav_item.title != "________" %}
    <li class="toctree-l1 {% if nav_item.active%}current{%endif%}">
        <a class="{% if nav_item.active%}current{%endif%}" href="{{ nav_item.url }}">{{ nav_item.title }}</a>
...
    </li>
  {% endif %}
{% endif %}

The reason I prefer this approach to using markdown metadata is that I'd rather specify what is hidden or included in the same place where I'm organizing the menu layout. If it had to be in the metadata, it would be spread across individual markdown files. That would be useful if I didn't have to list out all the pages in mkdocs.yml, but that only works if pages is omitted altogether, in which case I cannot control the menu layout at all (undesired for my project with lots of files and structure).

If you'd like the underscores hack upstream in readthedocs theme, I'm happy to put up a 2-line PR (plus documentation). Perhaps by now there is a better solution for what I'm doing, if so please advise. I couldn't tell what behavior would be delivered by the referenced #689.

@jberkel
Copy link

jberkel commented Nov 18, 2015

@dmehra a bit more flexible approach is simply to check for a title beginning with '_':

{% if not nav_item.title.startswith("_") %}
pages:
- Concepts:
   - 'Overview': 'concepts/overview.md'
   - '_QuickRef': 'concepts/quick_ref.md'

This way you can easily enable / disable headings, and you don't need to count the number of "_" used.

@robodude666
Copy link

@jberkel That's a great idea! Certainly less ambiguous than having a whole bunch of **HIDDEN** titles in your pages.

This got me thinking... What if mkdocs "borrows" from Python, and any *.md filenames that started with a _ or __ were "hidden" and not published in the toc (unless a flag is disabled in the yml config)?

This allows users who don't use pages and rely on mkdoc's self-discovery to maintain hidden pages, while allowing users of pages to specify pages without voodoo hacks.

@dmehra
Copy link

dmehra commented Nov 19, 2015

I am using @jberkel title.startswith("_") successfully in my custom scheme right now. The _*.md filename based idea by @robodude666 is interesting, it would avoid having to maintain a long list of ____ Page Title XYZ entries in mkdocs.yml; however to make the pages appear/disappear in the sidebar, one would have to rename the files, as opposed to editing in a single config file. I think the top-down vs bottom-up specification comes down to a personal preference, so perhaps supporting both ways (with a config flag) is worthwhile.

@shichao-an
Copy link

My workaround is to hack the nav.html template by adding the following line somewhere in the very beginning:

{% set hidden_titles = ["foo", "bar"] %}

Then, the nav for loop is something like this:

...
{% for nav_item in nav %}
  {% if nav_item.title not in hidden_titles %}
...

This does not affect the naming structure of your pages and you can restore the hidden pages by removing them from the hidden_titles anytime you want.

@slackmoehrle
Copy link

+1 for the ideas. Thanks everyone. This was what I needed.

@slackmoehrle
Copy link

@waylan So I have:

- 'Editors & Tools':
      - 'Studio': 'editors_and_tools/studio.md'
      - '________': 'editors_and_tools/Workspace_Overview/en.md'

and in nav.html:

<!-- Expanded navigation -->
        <div class="navbar-collapse collapse">
            {% if include_nav %}
                <!-- Main navigation -->
                <ul class="nav navbar-nav">
                {% for nav_item in nav %}

                  {% if nav_item.title != "________" %}

                      {% if nav_item.children %}
                          <li class="dropdown{% if nav_item.active %} active{% endif %}">
                              <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ nav_item.title }} <b class="caret"></b></a>
                              <ul class="dropdown-menu">
                              {% for nav_item in nav_item.children %}
                                  {% include "nav-sub.html" %}
                              {% endfor %}
                              </ul>
                          </li>
                      {% else %}
                          <li {% if nav_item.active %}class="active"{% endif %}>
                              <a href="{{ nav_item.url }}">{{ nav_item.title }}</a>
                          </li>
                      {% endif %}

                  {% endif %}

                {% endfor %}
                </ul>
            {% endif %}

but when I deploy, I still see items with ________

I also tried: {% if not nav_item.title.startswith("_") %} too

What mistake did I make?

@shichao-an
Copy link

@slackmoehrle

I think nav_item.title refers to upper-level titles, e.g. 'Editors & Tools'.

________ is in nav_item.children.

You need to put the if inside {% for nav_item in nav_item.children %}

@dmehra
Copy link

dmehra commented Jan 29, 2016

If I correctly remember (set up mkdocs a few months ago, works great!) nav.html is for the main page navigation. What you want to modify is toc.html because that controls the left pane menu. Here is mine, using if not nav_item.title.startswith("_"):

{% if nav_item.children %}
    <ul class="subnav">
    <li><span>{{ nav_item.title }}</span></li>

        {% for nav_item in nav_item.children %}
            {% include 'toc.html' %}
        {% endfor %}
    </ul>
{% else %}
  {% if not nav_item.title.startswith("_") %}
    <li class="toctree-l1 {% if nav_item.active%}current{%endif%}">
        <a class="{% if nav_item.active%}current{%endif%}" href="{{ nav_item.url }}">{{ nav_item.title }}</a>
<!-- Removed the subsection list that duplicates subsection title in most cases -->
    </li>
  {% endif %}
{% endif %}

@slackmoehrle
Copy link

@dmehra I am trying to modify both the left hand pane and the menu navigation so that pages with "________" don't appear at all, anywhere. They are just linked to in other docs.

@slackmoehrle
Copy link

@shichao-an Thank you. It works as it should. I appreciate your reply very much.

@gsouf
Copy link

gsouf commented Mar 24, 2016

Instead of finding workaround, it there a plan to make it a native feature ?

@majkinetor
Copy link

That depends on the context. Hidding is often enough - can u guess my secret gist link?

@majkinetor
Copy link

Besides, you can configure web server to ask for auth on specific pages/dirs.

But you need to have files, hence the request.

@gsouf
Copy link

gsouf commented Jan 17, 2018

Not sure that's the subject of the ticket

@waylan
Copy link
Member

waylan commented Jan 17, 2018

Ok, let's keep the conversation on topic please. As it stands, this feature is definitely going to be added and more "me too" comments will only add to the noise. As stated in a previous comment, it is a work in progress. We are volunteers working on this in our spare time and more noise here doesn't give us more spare time.

weierophinney added a commit to weierophinney/zf-mkdoc-theme that referenced this issue Jan 17, 2018
This is a hack learned from the mkdocs issue tracker:

- mkdocs/mkdocs#699 (comment)

Essentially, with this in place, if a page _title_ begins with `_`, it
will not be included in the navigation.

Additionally, this patch goes a step further, and the rendered markdown
of such pages is injected only into the `<head>` section of the built
document, with no other content. This allows for a very quick redirect,
with no content present to index.

This is useful when you want to preserve link continuity. The old page
can continue to exist, but no pages on the site will reference it, which
means that search engines will eventually stop crawling it.

The stated recommendation in the README is to replace the contents of
that page with JS and/or a meta refresh in order to force a redirect
once loaded; most search engines will notice these and honor them,
removing the page from their search results.
froschdesign pushed a commit to froschdesign/zf-mkdoc-theme that referenced this issue Jan 27, 2018
This is a hack learned from the mkdocs issue tracker:

- mkdocs/mkdocs#699 (comment)

Essentially, with this in place, if a page _title_ begins with `_`, it
will not be included in the navigation.

Additionally, this patch goes a step further, and the rendered markdown
of such pages is injected only into the `<head>` section of the built
document, with no other content. This allows for a very quick redirect,
with no content present to index.

This is useful when you want to preserve link continuity. The old page
can continue to exist, but no pages on the site will reference it, which
means that search engines will eventually stop crawling it.

The stated recommendation in the README is to replace the contents of
that page with JS and/or a meta refresh in order to force a redirect
once loaded; most search engines will notice these and honor them,
removing the page from their search results.
@waylan waylan added this to To do in Pages Refactor Feb 5, 2018
@waylan waylan mentioned this issue Mar 4, 2018
weierophinney added a commit to froschdesign/zf-mkdoc-theme that referenced this issue Apr 4, 2018
This is a hack learned from the mkdocs issue tracker:

- mkdocs/mkdocs#699 (comment)

Essentially, with this in place, if a page _title_ begins with `_`, it
will not be included in the navigation.

Additionally, this patch goes a step further, and the rendered markdown
of such pages is injected only into the `<head>` section of the built
document, with no other content. This allows for a very quick redirect,
with no content present to index.

This is useful when you want to preserve link continuity. The old page
can continue to exist, but no pages on the site will reference it, which
means that search engines will eventually stop crawling it.

The stated recommendation in the README is to replace the contents of
that page with JS and/or a meta refresh in order to force a redirect
once loaded; most search engines will notice these and honor them,
removing the page from their search results.
ikit pushed a commit to REGOVAR/Regovar that referenced this issue May 9, 2018
@waylan waylan moved this from To do to In progress in Pages Refactor Jun 3, 2018
@waylan waylan mentioned this issue Jun 8, 2018
@waylan waylan closed this as completed in 34ef3ca Jun 28, 2018
Pages Refactor automation moved this from In progress to Done Jun 28, 2018
melo added a commit to melo/docker-mkdocs-alpine that referenced this issue Jul 1, 2018
This will skip menu entries if they start with a “_”

See mkdocs/mkdocs#699 (comment)
for details
@ojacques
Copy link

Side note, but helpful for some: mkdocs-awesome-pages-plugin allows to build, but hide an entire directory.

image

@matchavez
Copy link

Can you just make it a "" in the nav?

@matchavez
Copy link

Well, turns out this was updated with #1504 - all pages are now built; just leave them out of the nav structure.

@mkdocs mkdocs locked as resolved and limited conversation to collaborators Jan 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests