Blogging with MkDocs
Warning
This post was written before the built-in blog plugin was released.
I love MkDocs - especially with the Material for MkDocs theme - and after accidentally killing my blog (yet again), I wanted to try and rebuild it with plain Markdown files and MkDocs.
There are a number of posts, queries, and plugins around using MkDocs for a blog instead of documentation. This time around I want to keep it simple - close to a vanilla installation, or at least with the expectation that things will still broadly work if one of the plugins breaks during an upgrade.
It's worth noting I'm already familiar enough with MkDocs to be comfortable with it, which is why this feels simple to me. It might not feel simple to someone else.
Info
Most of these notes are just a summary of the amazing docs on the Material for MkDocs site - you should definitely have a browse through, there's more than I could cover here.
MkDocs + Material for MkDocs
Start with a basic mkdocs.yml
. MkDocs expects your source files to live in a
subdirectory next to the mkdocs.yml
(if this bother you, the
mkdocs-simple-plugin
is
worth checking out).
I've called my directory src/
, since they aren't really "docs" at this point:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
This sets up the basics:
- The
docs_dir
pointing to oursrc/
directory - Copyright and attribution information
- The
material
theme - A customised header logo
- Enable tabs and make them sticky on scroll
At this point, because I'm not really a Python developer, I also have a simple requirements.txt
:
1 2 |
|
To create the home page content, create either src/README.md
or
src/index.md
according to your preference.
Post Order - Most Recent First
Blog posts live in src/posts
. By default, MkDocs will sort alphanumerically
by filename. ISO-8601 is well suited for sorting, so my blog posts are named as
src/posts/${YYYY}-${MM}-${DD}-${article-slug}.md
.
But blog posts are typically presented in reverse order - with the most recent post first.
The
mkdocs-awesome-pages-plugin
provides an order
option that will do just that.
So it gets added to requirements.txt
:
1 |
|
And configured in mkdocs.yml
:
1 2 3 |
|
(Once we add our own list of plugins, we have to also include the default
search
plugin explicitly)
And then we add a .pages
file to src/posts/.pages
:
1 |
|
I've chosen to break down posts by year for a bit more organisation,
so .pages
is also repeated in the src/pages/2021/
directory, and will need
to be repeated in other years.
If you're thinking about folder names broken down by ${YYYY}/${MM}
- you can, but I found it tedious to use .pages
to rename the folders to the month of the year. And I don't blog that often
Post Index - All Posts
For part of the home page illustration (which we'll get to in a minute), I
wanted to be able to link to the posts/
page (even though it's already in the
header tabs).
By default, MkDocs will select the first article in the navigation as the
"index" for the posts/
page - which means I can't link to it without updating
it every time I write a new post.
The simplest way around this is a src/posts/index.md
, but that will just be an empty page.
The
mkdocs-pagenav-generator
fixes this - it works with the awesome-pages
plugin to provide a
{nav}
placeholder in the Markdown. This is perfect for
generating a list of all blog posts for the index page in src/posts/index.md
:
# All Posts
{nav}
And adding it to the plugins list:
1 2 3 4 |
|
The only confusing part was the syntax for requirements.txt
when pulling
directly from GitHub - I prefer to pin dependencies to some kind of committish,
and the repository isn't tagged, so it's a raw commit:
1 |
|
This also makes the navigation sidebar rather redundant, so we'll customise that later.
That's the basics of a) MkDocs with a decent theme, b) blog posts in chronological order, and c) a post index.
Basic Customisation
I've gone a little bit further with help from the Material for MkDocs documentation:
- Changing the colors (including the light/dark theme toggle in the header)
- Changing the fonts
- Hiding the sidebars
- Content area width
- Admonitions
- Syntax highlighting
And the mkdocs-git-revision-date-localized-plugin for adding created/last updated dates to the footer of the blog posts.
Customising the Landing Page
Customising the landing page is mostly documented in Material for MkDocs issues #2057 and #1996.
Mine looks something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Which replaces the main index page for the site with an include of home.svg
,
which is adapted from the awesome illustrations at unDraw.
This could be done with a normal index.md
- the difference here is the
removal of the "next" and "previous" links above the footer.
That's All
As mentioned earlier, definitely check out the docs for Material for MkDocs -
there's simply loads of goodies. Emojis, content tabs, and footnotes are some
of my favourites, and versioning support with
mike
is brilliant for more technical
docs, which I'll try and cover soon.
You can see the full setup at GitLab, including the CI/CD pipeline which isn't covered here.
Created: June 20, 2021