For a side project I’ve been looking into static site generators and came across MkDocs or more specifically Material for MkDocs, which bundles a nicer theme and some useful default plugins into one package and with great documentation. As the name implies MkDocs was primarily developed to write documentation, but it also works quite nicely for other types of static sites. I haven’t investigated the full customization potential, but maybe it’s also something for SFML, given that we want to move our tutorials into a more easily modifiable format.
In short MkDocs is using Python to generate HTML pages from Markdown files. As the documentation for Material for MkDocs are so good, there isn’t much need for me to repeat all the steps, instead I’ll post my mkdocs.yml
file section by section with some comments for the non-obvious options:
site_name: <Project>
site_url: https://<Project>.com
repo_url: https://github.com/eXpl0it3r/<Project>
repo_name: <Project>
docs_dir: pages
The repo_*
variables are quite useful to directly link the repository of the project on the top including starts, latest tag and number of forks.
The doc_dir
allows you to pick a different sub-directory than the default docs/
to put your Markdown files under.
theme:
name: material
logo: assets/img/project-logo.png
favicon: assets/img/project-logo-32x32.png
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: indigo
toggle:
icon: material/weather-night
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: indigo
toggle:
icon: material/weather-sunny
name: Switch to light mode
features:
- content.code.copy
- navigation.instant
- navigation.instant.progress
- navigation.tracking
- navigation.tabs
- navigation.sections
- navigation.expand
- navigation.path
- navigation.indexes
- navigation.top
- navigation.footer
icon:
repo: fontawesome/brands/github
As we’re working with Material for MkDocs, the theme is of course material
. Out-of-the-box you can add a simple configuration to support dark mode and customize the switch icons.
The theme has a lot of different features which you can optionally enable, especially around navigation. I like that you can define the behavior of page pre-fetching and moving between pages. So you don’t do a full page reload, but it will instead act as a single page application (SPA) and you can even have the additional pages loaded in the background, so navigation happens instantly and the user won’t even have to fetch new content. Kind of the magic that React is implementing with its server side components and hydration.
extra:
social:
- icon: fontawesome/brands/mastodon
link: https://fosstodon.org/@<Project>
name: <Project> on Fosstodon
- icon: fontawesome/brands/twitter
link: https://twitter.com/<Project>
name: <Project> on Twitter
extra_css:
- assets/css/main.css
extra_javascript:
- assets/js/mathjax.js
- https://polyfill.io/v3/polyfill.min.js?features=es6
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
Social buttons are configured with a breeze and it even supports Mastodon. I still need to look into setting up social cards (i.e. the preview you see when posting a link on Discord or Twitter), but they are also supported out-of-the-box.
If you want to include some custom CSS or JavaScript, you can easily do this here as well. For example, I made the logo in the top left corner slightly larger to what the theme defaults to.
markdown_extensions:
- pymdownx.arithmatex:
generic: true
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
plugins:
- search
- literate-nav:
nav_file: navigation.md
implicit_index: false
tab_length: 4
- redirects:
redirect_maps:
"old/path/file.md": "new/path/file.md"
Plain Markdown is often not enough, as is the case for me, since I want to display some mathematical formulas, thus I enabled Arithmatex which uses MathJax to render the formulas in the browser. See the full list of Markdown extensions.
For plugins, I use the built-in search, that however needs to be enabled as plugin when using other plugins, literate-nav for a more customizable navigation, and redirects to ensure old links continue working and point to the new page.
validation:
nav:
omitted_files: info
not_found: warn
absolute_links: info
links:
not_found: warn
absolute_links: info
unrecognized_links: info
And finally, there’s validation options for links, that will return info or warning statements about links that couldn’t be resolved properly during build time, which is quite handy to stay informed about broken links.
Once you’ve set everything up you can run either mkdocs serve
to get a preview with hot reload hosted locally or mkdocs build
to create a publishable bundle.
While checking out the literate-nav plugin, I recognized the name of the author in the URL and only then did I realized that Oprypin is also the current maintainer of MkDocs itself. Oprypin has helped out with a few things in SFML and CSFML, and has created the Crystal SFML binding.
The journey doesn’t stop there. In a future blog post, I show the setup I used to publish to Cloudflare pages.
2 thoughts on “Static Site Generation from Markdown with MkDocs”