Some cool plugins for your mkdocs based site

In a previous article, I've discovered a super cool tool to make nice documentation site : mkdocs. In this article, I'll present some nice plugins available in mkdocs ecosystem (which is very rich BTW, a catalog is available here for a quite complete view of many plugins).

As prerequisites, you should have install :

  • mkdocs-materialtheme

  • large icons set

      markdown_extensions:
      ...
        - attr_list
        - pymdownx.emoji:
            emoji_index: !!python/name:material.extensions.emoji.twemoji
            emoji_generator: !!python/name:material.extensions.emoji.to_svg
    

โ„น๏ธ You can easily search for cool icon here

Pretty timelines

First, one is neoteroi.timeline plugin. With it, you'll be able to easily display some fancy timeline in your website

Installation

First, install it with pip

pip install neoteroi.timeline

If you're deploying your site with some CICD pipeline, don't forget to add the dependency in your requirements.txt file to automatically install the plugin when building the site

neoteroi-mkdocs

To enable it in your project, you need to add these elements in your mkdocs.yml configuration file

extra_css:
  - css/neoteroi-mkdocs.css
  - css/neoteroi-timeline.css

  ...

markdown_extensions:
  - neoteroi.timeline

Also, you need to download the associated CSS files and add them into the css directory in your docs folder

Sample

Now that neoteroi-timeline plugin is enabled, we can use it in a page. Timeline can be described in JSON or YAML. Here I'll use the JSON version :

:timeline::

## <your_timeline>

::/timeline::
[
    {
        "title": "๐Ÿ“บ The Return of the Jedi",
        "sub_title": "1983",
        "content": "๐Ÿ“ Movie is a fantastic story about a green old wise",
        "icon": ":fontawesome-brands-rebel:"
    },
    {
        "title": "๐Ÿ’ Lords of the Ring",
        "sub_title": "2001",
        "content": "๐Ÿ“ Movie about a fantastic journey in the valley",
        "icon": ":material-ring:"
    }
]

This will look like this in your site

Each timeline item is composed of 1 mandatory attribute and 4 optional ones:

  • title to set the item title

  • (optional) sub_title that will be display on the left of the timeline, for instance the datetime of the item

  • (optional) content giving some explanation regarding the item

  • (optional) icon to change the icon displayed

  • (optional) key to pick the color for the icon. If not set, the plugin will do some round robin in a predefined set of colors.

Another plugin is search. With this one, you'll be able to easily add some simple but efficient search engine in your website. It's a static one but ease to search some information within your site.

Installation

In the mkdocs.yml, just add the plugins in your configuration

plugins:
  - search

Usage

When rendering the site, a search input is available on the top right corner. Just time your keyword, and the plugin will display the abstract containing the keyword and a link to the page containing it

Embedded videos

Sometimes embedding videos is quite useful. With mkdocs-video plugin, it's super easy to do this

Installation

First, install it with pip

pip install mkdocs-video

If you're deploying your site with some CICD pipeline, don't forget to add the dependency in your requirements.txt file to automatically install the plugin when building the site

mkdocs-video

In your mkdocs.yml configuration file, enable the plugin

plugins:
  # Include videos
  - mkdocs-video

Sample

Once enable, you can include video in your pages using the plugin syntax

![type:video](https://www.youtube.com/embed/mxhpCvSmFK4?si=qSGg_mbOG8WNaVQK)

The video is then embedded in the page

Dynamic content generation

Another interesting is to be able to generate some pages based on dynamic data. With gen-files plugin, you can generate page at the site building phase based on data coming from an API for instance. It's not real dynamic data as the page is built during the global site generation, but in a CICD pipeline you can easily generate an up-to-date page, for instance for an API documentation.

Installation

First, install it with pip

pip install mkdocs-gen-files

If you're deploying your site with some CICD pipeline, don't forget to add the dependency in your requirements.txt file to automatically install the plugin when building the site

mkdocs-gen-files

In your mkdocs.yml configuration file, enable the plugin and list of the scripts to be executed to generate the page

plugins:
  # Generate page
  - gen-files:
      scripts:
        - scripts/gen_page.py

Sample

Now we need to implement our Python script to generate the file. In this sample, I'm calling the Hashnnode GraphQL API to list all my articles in a page

import mkdocs_gen_files
import json
from gql import gql, Client
from gql.transport.aiohttp import AIOHTTPTransport
from datetime import datetime

# Select your transport with a defined url endpoint
transport = AIOHTTPTransport(url="https://gql.hashnode.com/")

# Create a GraphQL client using the defined transport
client = Client(transport=transport, fetch_schema_from_transport=True)

# Provide a GraphQL query
query = gql(
    """
    query Publication {
    publication(host: "yodamad.hashnode.dev") {
        isTeam
        title
        posts(first: 50) {
        edges {
            node {
                title
                url
            }
        }
        }
    }
    }
"""
)

# Execute the query on the transport
result = client.execute(query)

articles = result["publication"]["posts"]["edges"]
raw = json.dumps(articles)
data = json.loads(raw) 

with mkdocs_gen_files.open("articles/index.md", "w") as f:
    print("# ๐Ÿ“ My articles", file=f)
    # Iterate through the JSON array 
    for item in data: 
        print("## **" + item["node"]["title"] + "**", file=f)
        print("๐Ÿ”— [" + item["node"]["url"] + "](" + item["node"]["url"] + ")", file=f)

When running mkdocs build (or mkdocs serve), the plugin generates the page to be rendered

Then each time I generates my site, the listing of articles is up-to-date. Combined with for instance a scheduled rebuilding pipeline of the site, for instance every night, I'm sure that all my articles are listed.

โš  If you include some Python libraries for your generation script, don't forget to add them into the requirements.txt file.

section-index

By default, section in navigation cannot be associated with a page. But in some use cases, this can be useful for instance to have an explanatory page of the chapter and a list of all the pages included in the section and a quick description of each of them. The plugin section-index enables this feature

Installation

First, install it with pip

pip install mkdocs-section-index

If you're deploying your site with some CICD pipeline, don't forget to add the dependency in your requirements.txt file to automatically install the plugin when building the site

mkdocs-section-index

In your mkdocs.yml configuration file, enable the plugin

plugins:
  # Make section displayable in nav
  - section-index

Sample

Then, in the nav configuration part of the mkdocs.yml I can have a page associated with the section

nav:
  - Homepage : ./index.md
  - Stuff : 
    - ./stuff/index.md # Link for the section associated page
    - Articles: ./stuff/articles.md
    - Videos: ./stuff/videos.md

literate-nav

When building large site with rich pages structure, using the default behavior based on the nav keyword in the mkdocs.yml file can be heavy and polluting. With literate-nav plugin, you can externalize this configuration to a dedicated file (or several) and enrich navigation configuration in the meantime. For instance, the plugin supports the wildcard pattern * to include all pages under a specified directory

Installation

First, install it with pip

pip install mkdocs-literate-nav

If you're deploying your site with some CICD pipeline, don't forget to add the dependency in your requirements.txt file to automatically install the plugin when building the site

mkdocs-literate-nav

In your mkdocs.yml configuration file, enable the plugin

plugins:
  # Move navigation to a dedicated summary file
  - literate-nav:
      nav_file: navigation.md

Sample

Now, I can describe my navigation into the dedicated navigation.md file

* [๐Ÿก Homepage](./index.md)
* [๐Ÿ“ Articles](articles/index.md)
* [๐ŸŽ™๏ธ Confรฉrences 2024](talks/index.md)
    * [๐Ÿ—‚๏ธ Archives 2023](talks/2023.md)
    * [๐Ÿ—‚๏ธ Archives 2022](talks/2022.md)
* [๐ŸŽฅ Replays](videos/index.md)
* [๐ŸŽช Divers](others/index.md)
    * [๐ŸŽง Podcasts](others/podcasts.md)
    * [๐Ÿ“บ Broadcasts](others/broadcasts.md)

Coupled with the previous section-index plugin, I've now a nice navigation

Conclusion

To summarize, here are some interesting plugins i've discovered while building some new site about me #spoilerAlert

Again, mkdocs is really simple to use to write documentation and benefit from a large panel of plugins and a super active community. These plugins are just a quick overview of the large catalog available.

Official sites of the plugins:

4
Subscribe to my newsletter

Read articles from Matthieu Vincent directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Matthieu Vincent
Matthieu Vincent

TechAdvocate DevSecOps / Cloud platform Lead Architect @ Sopra Steria Speaker @ Devoxx, Snowcamp, Breizhcamp, GitLab Connect and internally Co-Founder of Volcamp IT Conference @ Clermont-Fd (https://volcamp.io) GitLab Hero