New, as of version 0.4.20.
A pluglet is a preinstalled module for mkdocs-macros, which is installed thanks to Pythons standard packaging process.
thing needed (as a bare minimum), is to implement a single function,
def define_env(env): ....
What makes a pluglet different from a plain module?
The only difference between a pluglet and an ordinary
mkdocs-macros module (typically
is that the pluglet is preinstalled. In this way, you can
benefit from pluglets written by others, and you could share the
pluglets that you wrote.
A pluglet can do two things that any mkdocs-macro module can do:
- Define macros.
- Perform changes on the architecture of the website.
What makes a pluglet different from a plugin?
A pluglet is distinct from an MkDocs plugin. A pluglet is a more lightweight tool that sits over the mkdocs-macros plugin and uses the framework provided by it.
There is no need to implement a subclass of the
only to declare a
Could a pluglet do everything a plugin can do?
The answer is, quite a lot, but not everything. MkDocs plugins are able to rely on a wide range of events, which are hooks for acting on the website at various stages of the config/build process.
A mkdocs-macros pluglet operates mostly on the on_config event of MkDocs thanks to
define_env(env)hook; but its use can be extended thanks to other hooks.
Using existing pluglets
Declaring a pluglet for an MkDocs project
For your specific documentation project, you may call already
installed pluglets (which would appear with
pip list | grep mkdocs-macros
It is a list, so that you can declare one or more:
plugins: ... - macros: modules: [mkdocs_macros_test]
plugins: ... - macros: modules: [mkdocs_macros_foo, mkdocs_macros_bar]
Every pluglet specified in the
moduleslist should be available.
However, if the pluglet cannot be found, mkdocs will attempt to install it
pip3 install) from the standard repositories (Pypi and others defined locally). If not, mkdocs will fail and exit.
Make installations easier!
The purpose of this feature is to facilitate the management of environments with several mkdocs websites, typically when a pluglet is designed for a whole company, project, etc.
In this way, the macros and filters declared in the pluglet will work out of the box, as long as the pluglet is properly defined in the config file (and the pluglet is auto-installable).
In some cases, the name of the source package i:
plugins: ... - macros: modules: [mkdocs-macros-test:mkdocs_macros_test]
In the example above
mkdocs-macros-test is the package source, and
mkdocs_macros_test is the package name for the
If those names are correct everything should fall into place when you type the
mkdocs serve or
mkdocs build commands.
Implementing a new pluglet
You can develop pluglets for mkdocs-macros-plugin and publish them on github and pypi.
How to name a pluglet
The names for pluglets are not constrained. As a naming convention, we strongly recommend:
- a package name starting with
- an import name starting
mkdocs_macros_, i.e. replacing the hyphen (
-) symbol by underscore (
Typical structure of a pluglet
You will find a simple example with the
mkdocs-test pluglet, available on gihub.
setup.py file will typically have this form:
from setuptools import setup setup( name='mkdocs-macros-foo', version='0.0.1', description="Foo library for macros plugin", packages=['mkdocs_macros_foo'], license='<YOUR CHOICE>', author='Joe Bloe' )
The structure will be typically like so:
├── LICENSE.md ├── README.md ├── mkdocs_macros_test.py └── setup.py
or like so (if it is more complex):
├── LICENSE.md ├── README.md ├── mkdocs_macros_test │ └── __init__.py | └── util.py └── setup.py
The subdirectory containing
the code will have to be called
How to write the code
For the code itself, proceed as for a usual module:
""" Code of the pluglet """ def test_fn(x:float): "Test function" return x * 4 / 3 def say_hello(s:str): "Test procedure" return "<i>Hello %s</i>" % s def define_env(env): "Declare environment for jinja2 templates for markdown" for fn in [test_fn, say_hello]: env.macro(fn) # you could, of course, also define a macro here: @env.macro def test_fn2(s:str): return "I am displaying this: %s" % s