跳转至

mkdocs-macros-plugin宏插件

mkdocs-macros-plugin宏插件文档

通过变量和宏释放Mkdocs的威力。号称:

Note

这不只是一个插件,它是一个迷你框架!

设置#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
plugins:
    - search
    - macros:
        # 替换默认的jinja宏标志{{}},否则类似的地方可能报错
        # [[% raw %]]
        j2_block_start_string: '[[%'
        j2_block_end_string: '%]]'
        j2_variable_start_string: '[['
        j2_variable_end_string: ']]'
        # [[% endraw %]]    

HTML注释、code block等都无法阻止宏转换。阻止方法:

  • 当前文档不应用宏,设置markdown文件的metadata:ignore_macros: true
  • jinja2单行字符串{{ "{{ 2 + 2 }}" }} {{ '{{ "Hello world" }}' }}
  • 多行则用{{ raw }} {{ endraw }}标签包裹(花括号改成你的设置)
  • lua代码块中长文本应改成类似[-[ ... ]-]的样子;TEX中的{紧接#,或紧接%,会被看作行内注释标签(comment tag)的开始,用空格分开即可(对代码本身有副作用)。

用宏扩展markdown页面文件#

内置的宏对象#

Object Description
config The standard config information on MkDocs' environment.
page 当前页的资料
navigation 所有页面/组的列表
environment Data on the system on which MkDocs is currently running.
plugin Arguments of the macro plugin, in the config file
git Information on the git version of the website (if part of a git repository)
files 文档结构 (for advanced users who know how to manipulate the mkdocs.structure.files.Files object, as well as mkdocs.structure.files.File objects)

查看详细信息:

1
2
3
[[% raw %]]
[[ context(page) | pretty ]]
[[% endraw %]]    

Note

本页以下的宏信息,就是像上面这样生成的。

page#

[[ context(page) | pretty ]]

[[ context(navigation) | pretty ]]

[[ context(navigation.pages) | pretty ]]

config#

[[ context(config) | pretty ]]

过滤器#

[[ context(filters)| pretty ]]

Jinja2内置过滤器#

Jinja2内置过滤器的文档

本地查看:

1
2
3
[[% raw %]]
[[ context(filters_builtin) | pretty ]]
[[% endraw %]]    

自定义模块:宏、过滤器和变量#

插件的威力体现在这里!

模块必须包含define_env()函数,其中包含宏、过滤器和变量声明。 如在根目录中建立main.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import math
def define_env(env):
    """
    This is the hook for defining variables, macros and filters

    - env.variables: the dictionary that contains the environment variables
    - env.macro: a decorator function, to declare a macro.
    """

    # add to the dictionary of variables available to markdown pages:
    env.variables['baz'] = "John Doe"

    # NOTE: you may also treat env.variables as a namespace,
    #       with the dot notation:
    env.variables.baz = "John Doe"

    @env.macro
    def mymacro():
        return "this is mymacro!!!"

    # If you wish, you can  declare a macro with a different name:
    def f(x):
        return x * x
    env.macro(f, 'barbaz')

    # or by adding it to the `env.variables` dictionary
    # or to export some predefined function
    env.macro(math.floor) # will be exported as 'floor'

    # create a jinja2 filter
    # or by adding it to the env.filters dictionary
    @env.filter
    def reverse(x):
        "Reverse a string (and uppercase)"
        return x.upper()[::-1]

在markdown中使用:

1
2
3
[[% raw %]]
[[ mymacro() ]]
[[% endraw %]]    

效果:

[[ mymacro() ]]

env的成员#

Item Type Description
variables attribute The namespace that contains the variables and macros that will be available in mardkown pages with {{ ... }} notation. This dictionary is initialized with the values contained in the extra section of the configuration file (and optionally, with external yaml files). This object is also accessible with the dot notation; e.g. env.variables['foo'] is equivalent to env.variables.foo.
macro function A decorator function that you can use to declare a Python function as a Jinja2 callable ('macro' for MkDocs).
filters attribute A list list of jinja2 filters (default None)
filter function A decorator for declaring a Python function as a jinja2 custom filter
project_dir attribute The source directory of the MkDocs project (useful for finding or including other files)
conf attribute The content of the config file (mkdocs.yaml).
config attribute This can be a useful object; it contains the global context for MkDocs.
page attribute The information on the page being served (such as the title, etc.). For more information on its content, see MkDoc's description of the page object.

模块可用的更多的函数钩子#

Function Description Typical Use Triggered by MkDoc's event
define_env(env) Main function Create macros, filters, etc. on_config
on_pre_page_macros(env) Executed just before the Jinja2 directives (markdown page) have been rendered Directly modify a markdown page on_page
on_post_page_macros(env) Executed just after the Jinja2 code (markdown page) have been rendered Directly modify a markdown page on_page
on_post_build(env) Executed after the html pages have been produced Add files to the website on_post_build

Mkdocs全局环境global-context#

都包裹在或的env.conf下,例如

  • env.conf['nav'],即是nav
  • env.conf['pages'],即是pages
  • env.conf['page']['meta'],即是page.meta
  • env.config,宏插件自身的配置

用例#

列出20天以来(据page.meta.Modified)的文章标题和日期。过滤器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 在index页中使用只能取到index页自身,不知何故
@env.filter
def fromdays(navigation_pages, days):
    "滤出今天之前X天内的新帖"

    l = []
    for i in navigation_pages:
        if hasattr(i, "meta"):
            meta = i.meta
            if ("Modified" in meta and meta["Modified"]): 
                page_time = datetime.datetime.strptime(str(meta["Modified"]).split(" ")[0], '%Y-%m-%d')
                if datetime.datetime.today() - page_time < datetime.timedelta(days=days):
                    l.append(i)
    return l

markdown中的jinja模板:

1
2
3
4
5
[[% raw %]]
[[% for page in navigation.pages|fromdays(20) %]]
- [ [[ page.meta.title ]][[ page.meta.Modified ]] ](https://blog.xiiigame.com/2021-03-12-mkdocs-macros-plugin%E5%AE%8F%E6%8F%92%E4%BB%B6/)
[[% endfor %]]
[[% endraw %]]    

效果:

[[% for page in navigation.pages|fromdays(20) %]] - [[ page.meta.title ]][[ page.meta.Modified ]] [[% endfor %]]

列出10篇最近更新的文章(据page.meta.Modified)。过滤器:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 在index页中使用只能取到index页自身,不知何故
@env.filter
def last_blogs(navigation_pages, the_last_num):
    "滤出最新的X个新帖"

    l = []
    for i in navigation_pages:
        if hasattr(i, "meta"):
            if ("Modified" in i.meta  and i.meta["Modified"]): 
                l.append(i)
                print(f"{i.title}-{i.meta['Modified']}")
            else:
                print(f"没有Modified{i.title}")
        else:
            print(f"没有meta:{i.title}-{i.meta['Modified']}")
    l = sorted(l, key=lambda x: str(x.meta["Modified"]), reverse=True)
    # print(f'【调用last_blog】')
    # print(l)
    return l[:the_last_num]

markdown中的jinja模板:

1
2
3
4
5
[[% raw %]]
[[% for page in navigation.pages|last_blogs(10) %]]
- [ [[ page.meta.title ]][[ page.meta.Modified ]] ](https://blog.xiiigame.com/2021-03-12-mkdocs-macros-plugin%E5%AE%8F%E6%8F%92%E4%BB%B6/)
[[% endfor %]]
[[% endraw %]]    

效果:

[[% for page in navigation.pages|last_blogs(10) %]] - [[ page.meta.title ]][[ page.meta.Modified ]] [[% endfor %]]

更强大的pluglets#

查看例子

高级用法#

评论