0

I'm using MkDocs with the Material theme. I'd like to build a site that looks a little like the Stripe API docs.

By default, the Material theme puts .md documents in the sidebar on the left, and the headings withing those documents in a Table of Contents sidebar on the right. I'd like to put it all on the left:

Introduction
  A ## heading here
  Another heading
Getting Started
  Subsection
  etc.

I could do this by making every entry its own document, but I'd prefer to have only one document per major heading, with the table of contents consisting of subheadings underneath. Possible?

Update:

I have made some progress.

First, extend the theme by by following these instructions: https://squidfunk.github.io/mkdocs-material/customization/

Second, get rid of the TOC on the right by overriding the "site_nav" template block. In main.html, just copy the existing site_nav block from base.html, then comment out the "Table of contents" section.

Third, copy the nav-item.html partial into the /partials directory and make modifications.

Now I'm stuck. It looks like nav-item.html does have code to render the TOC under each item, and it does get rendered with a display:none. When I turn that off, though, the TOC does not appear properly.

I've done an hour of fiddling with CSS to get it to work with no success. Any ideas?

ccleve
  • 15,239
  • 27
  • 91
  • 157

4 Answers4

3

In your custom css file, write:

.md-sidebar--secondary {
  order: 0;
}

And in your mkdocs.yml, write:

extra_css:
  - assets/<custom_css_filename>.css
Zi Heng Xu
  • 31
  • 1
  • I believe this is the correct way, as messing up content of md-sidebar--secondary and md-sidebar--primary, as suggested in other answers, could lead to unwanted side effects (e.g. breaking navigation drawer on smaller resolution). – Oleksandr Kulkov Jun 03 '22 at 02:36
2

Your update to the question is exactly what I did so I'm unsure if this will be useful.

In mkdocs.yml add custom_dir to the theme:

theme:
  name: material
  custom_dir: overrides

Create a file overrides/main.html and observe the file you are replacing https://github.com/squidfunk/mkdocs-material/blob/master/material/base.html. Use the nav code but include the toc partial to get the following:

{% extends "base.html" %}

{% block site_nav %}
  <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
    <div class="md-sidebar__scrollwrap">
      <div class="md-sidebar__inner">
        {% include "partials/toc.html" %}
      </div>
    </div>
  </div>
{% endblock %}

Here is the result: Screenshot of mkdocs with changes

If you are looking at changing the table of contents to also include pages look into the partials in the git repo.

Luke
  • 2,851
  • 1
  • 19
  • 17
1

The easiest hack I've come up with is the following:

  1. In your mkdocs.yml, write:

    extra_javascript:
      - 'javascripts/extra.js'
    
  2. In your docs/javascripts/extra.js, write:

    document.addEventListener("DOMContentLoaded", function() {
        show_toc_left();
    });
    
    function show_toc_left(){
        document.querySelectorAll('.md-nav .md-nav--secondary')[0].setAttribute("style", "display: block; overflow: visible; color: #7d7f8e9c")
        document.querySelectorAll('.md-nav .md-nav--secondary label')[0].remove()
    }
    

This will show the TOC within your left side navigation menu of the currently active page.

1

You can also add this to the top of the individual page:

---
hide:
- toc
---
cjnygard
  • 136
  • 1
  • 3