开发主题

创建和发布自定义主题的指南。


注意

如果您正在寻找现有的第三方主题,它们列在社区 wiki页面和MkDocs 项目目录中。如果您想分享您创建的主题,您应该将其列在那里。

创建新主题时,您可以按照本指南中的步骤从头开始创建主题,也可以下载mkdocs-basic-theme作为基本但完整的主题,其中包含所有必要的样板文件。您可以在GitHub上找到此基础主题。它包含代码中的详细注释来描述不同的功能及其用法。

创建自定义主题

自定义主题的最低要求是main.html Jinja2 模板文件,该文件放在不是docs_dir子目录的目录中。在mkdocs.yml中,将theme.custom_dir选项设置为包含main.html的目录的路径。该路径应相对于配置文件。例如,给定此示例项目布局

mkdocs.yml
docs/
    index.md
    about.md
custom_theme/
    main.html
    ...

...您将包含以下设置在mkdocs.yml中以使用自定义主题目录

theme:
  name: null
  custom_dir: 'custom_theme/'

注意

通常,在构建自己的自定义主题时,theme.name配置设置将设置为null。但是,如果theme.custom_dir配置值与现有主题一起使用,则theme.custom_dir可以用来仅替换内置主题的特定部分。例如,使用上面的布局,如果您设置name: "mkdocs",则theme.custom_dir中的main.html文件将替换mkdocs主题中同名文件,但否则mkdocs主题将保持不变。如果您想对现有主题进行小的调整,这将非常有用。

有关更具体的的信息,请参见自定义主题.

警告

mkdocs_theme.yml文件中定义的主题的配置不会从theme.custom_dir加载。当整个主题存在于theme.custom_dir中并且theme.name设置为null时,则必须在mkdocs.yml文件中的theme配置选项中定义整个主题配置。

但是,当主题被打包以供分发并使用theme.name配置选项加载时,则需要mkdocs_theme.yml文件。

基本主题

最简单的main.html文件如下所示

<!DOCTYPE html>
<html>
  <head>
    <title>{% if page.title %}{{ page.title }} - {% endif %}{{ config.site_name }}</title>
    {%- for path in config.extra_css %}
      <link href="{{ path | url }}" rel="stylesheet">
    {%- endfor %}
  </head>
  <body>
    {{ page.content }}

    {%- for script in config.extra_javascript %}
      {{ script | script_tag }}
    {%- endfor %}
  </body>
</html>

来自mkdocs.yml中指定的每个页面的主体内容使用{{ page.content }}标签插入。样式表和脚本可以像普通 HTML 文件一样被引入到此主题中。导航栏和目录也可以通过navtoc对象自动生成和包含。如果您希望编写自己的主题,建议从内置主题之一开始并进行相应的修改。

注意

由于 MkDocs 使用Jinja作为其模板引擎,您可以使用 Jinja 的所有功能,包括模板继承。您可能注意到 MkDocs 中包含的主题广泛使用模板继承和块,允许用户轻松地从主题custom_dir覆盖模板中的小片段。因此,内置主题是在base.html文件中实现的,main.html扩展了它。虽然不是必需的,但第三方模板作者鼓励遵循类似的模式,并且可能希望为了一致性而定义与内置主题中使用的相同

从配置中获取 CSS 和 JavaScript

MkDocs 定义了顶层extra_cssextra_javascript配置。这些是文件列表。

主题必须包含链接这些配置中项目的 HTML,否则这些配置将无法使用。您可以在上面的基础示例中看到渲染它们的推荐方法。

版本 1.5 中的变更

config.extra_javascript列表的项目以前是简单的字符串,但现在变成了具有以下字段的对象:pathtypeasyncdefer

在此版本中,MkDocs 还获得了script_tag过滤器

过时的样式
  {%- for path in extra_javascript %}
    <script src="{{ path }}"></script>
  {%- endfor %}

此旧样式示例甚至使用了过时的顶层extra_javascript列表。请始终使用config.extra_javascript代替。

因此,一种稍微现代的方法如下所示,但它仍然过时,因为它忽略了脚本的额外属性

  {%- for path in config.extra_javascript %}
    <script src="{{ path | url }}"></script>
  {%- endfor %}
? 示例:新样式:

  {%- for script in config.extra_javascript %}
    {{ script | script_tag }}
  {%- endfor %}

如果您希望能够在保持主题与 MkDocs 的旧版本兼容的同时获取新的自定义项,请使用此代码段

向后兼容的样式
  {%- for script in config.extra_javascript %}
    {%- if script.path %}  {# Detected MkDocs 1.5+ which has `script.path` and `script_tag` #}
      {{ script | script_tag }}
    {%- else %}  {# Fallback - examine the file name directly #}
      <script src="{{ script | url }}"{% if script.endswith(".mjs") %} type="module"{% endif %}></script>
    {%- endif %}
  {%- endfor %}

主题文件

有一些文件,主题以某种特殊的方式处理这些文件。任何其他文件都只是从主题目录复制到构建站点时的site_dir中的相同路径。例如,图像和 CSS 文件没有特殊意义,并且按原样复制。但是,请注意,如果用户在他们的docs_dir中提供了具有相同路径的文件,那么用户的文件将替换主题文件。

模板文件

任何具有.html扩展名的文件都被视为模板文件,不会从主题目录或任何子目录中复制。此外,在static_templates中列出的任何文件都被视为模板,而不管其文件扩展名如何。

主题元数据文件

打包主题所需的各种文件也会被忽略。具体来说,mkdocs_theme.yml配置文件和任何 Python 文件。

点文件

主题作者可以通过以点开头文件或目录名称来明确地强制 MkDocs 忽略文件。以下任何文件都将被忽略

.ignored.txt
.ignored/file.txt
foo/.ignored.txt
foo/.ignored/file.txt

文档文件

所有文档文件都会被忽略。具体来说,任何 Markdown 文件(使用 MKDocs 支持的任何文件扩展名)。此外,主题目录中可能存在的任何 README 文件都会被忽略。

模板变量

主题中的每个模板都使用模板上下文构建。这些是主题可用的变量。上下文根据正在构建的模板而有所不同。目前,模板要么使用全局上下文构建,要么使用页面特定上下文构建。全局上下文用于不代表单个 Markdown 文档的 HTML 页面,例如 404.html 页面或 search.html。

全局上下文

以下变量在任何模板上全局可用。

config

config变量是 MkDocs 的配置对象实例,该对象是从mkdocs.yml配置文件生成的。虽然您可以使用任何配置选项,但一些常用的选项包括

nav变量用于创建文档的导航。nav对象是导航对象的可迭代对象,如nav配置设置所定义。

除了导航对象的可迭代对象外,nav对象还包含以下属性

homepage: Page | None instance-attribute

站点的首页的page对象。

pages: list[Page] instance-attribute

导航中包含的所有page对象的扁平列表。

此列表不一定是所有站点页面的完整列表,因为它不包含未包含在导航中的页面。此列表与用于所有“下一页”和“上一页”链接的页面列表和顺序相匹配。要获取所有页面的列表,请使用pages模板变量。

以下是一个基本用法示例,它将第一级和第二级导航输出为嵌套列表。

{% if nav|length > 1 %}
    <ul>
    {% for nav_item in nav %}
        {% if nav_item.children %}
            <li>{{ nav_item.title }}
                <ul>
                {% for nav_item in nav_item.children %}
                    <li class="{% if nav_item.active %}current{% endif %}">
                        <a href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
                    </li>
                {% endfor %}
                </ul>
            </li>
        {% else %}
            <li class="{% if nav_item.active %}current{% endif %}">
                <a href="{{ nav_item.url|url }}">{{ nav_item.title }}</a>
            </li>
        {% endif %}
    {% endfor %}
    </ul>
{% endif %}

base_url

base_url提供到 MkDocs 项目根目录的相对路径。虽然可以将其直接用于将其附加到本地相对 URL,但最好使用url模板过滤器,它在应用base_url时更智能。

mkdocs_version

包含当前 MkDocs 版本。

build_date_utc

一个 Python datetime 对象,表示文档在 UTC 中构建的日期和时间。这对于显示文档最近更新的时间很有用。

pages

项目中所有页面的File对象的扁平列表。此列表可能包含未包含在全局导航中的页面,并且可能与该导航中页面的顺序不匹配。每个Filepage对象可以从file.page访问。

page

在不是从 Markdown 源文件渲染的模板中,page变量为None。在从 Markdown 源文件渲染的模板中,page变量包含一个page对象。相同的page对象用作全局导航中的page 导航对象pages模板变量中的对象。

基础:StructureItem

所有page对象都包含以下属性

title() -> str | None

返回当前页面的标题。

在调用 read_source() 之前,此值为空。它也可以通过 render() 更新。

按顺序检查这些,并使用第一个返回有效标题的值

  • 初始化时提供的 value(从配置中传递)
  • 元数据 'title' 的 value
  • Markdown 内容中第一个 H1 的内容
  • 将文件名转换为标题
content: str | None 实例属性

渲染后的 Markdown 作为 HTML,这是文档的内容。

.render() 后填充。

toc: TableOfContents 实例属性

一个可迭代对象,表示页面的目录。toc 中的每个项目都是一个 AnchorLink

以下示例将显示页面的目录的前两级。

<ul>
{% for toc_item in page.toc %}
    <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
    {% for toc_item in toc_item.children %}
        <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
    {% endfor %}
{% endfor %}
</ul>
meta: MutableMapping[str, Any] 实例属性

Markdown 页面顶部包含的元数据的映射。

在这个例子中,我们在页面标题上方定义了一个 source 属性

source: generics.py
        mixins.py

# Page title

Content...

模板可以使用 meta.source 变量访问页面的此元数据。然后,这可以用于链接到与文档页面相关的源文件。

{% for filename in page.meta.source %}
  <a class="github" href="https://github.com/.../{{ filename }}">
    <span class="label label-info">{{ filename }}</span>
  </a>
{% endfor %}
url: str 属性

页面相对于 MkDocs site_dir 的 URL。

预期将其与 url 过滤器一起使用,以确保 URL 相对于当前页面。

<a href="{{ page.url|url }}">{{ page.title }}</a>
file: File 实例属性

页面正在从其渲染的文档 File

abs_url: str | None 实例属性

页面相对于服务器根目录的绝对 URL,由分配给 site_url 配置设置的值决定。该值包括 site_url 中包含的任何子目录,但不包括域名。 base_url 不应与该变量一起使用。

例如,如果 site_url: https://example.com/,则页面 foo.mdpage.abs_url 的值为 /foo/。但是,如果 site_url: https://example.com/bar/,则页面 foo.mdpage.abs_url 的值为 /bar/foo/

canonical_url: str | None 实例属性

当前页面相对于服务器根目录的完整规范 URL,由分配给 site_url 配置设置的值决定。该值包括域名和 site_url 中包含的任何子目录。 base_url 不应与该变量一起使用。

edit_url: str | None 实例属性

源代码库中源页面的完整 URL。通常用于提供链接以编辑源页面。 base_url 不应与该变量一起使用。

is_homepage: bool 属性

对于网站的首页,其值为 True,对于所有其他页面,其值为 False

这可以与 page 对象的其他属性结合使用,以改变行为。例如,要在主页上显示不同的标题

{% if not page.is_homepage %}{{ page.title }} - {% endif %}{{ site_name }}
previous_page: Page | None 实例属性

前一页面的 page 对象,或 None。如果当前页面是站点导航中的第一个项目,或者当前页面根本不包含在导航中,则该值为 None

next_page: Page | None 实例属性

下一页面的 page 对象,或 None。如果当前页面是站点导航中的最后一个项目,或者当前页面根本不包含在导航中,则该值为 None

parent: Section | None = None 类属性 实例属性

站点导航中项目的直接父级。如果在顶层,则为 None

children: None = None 类属性 实例属性

页面不包含子级,该属性始终为 None

active: bool 属性 可写

当为 True 时,表示此页面是当前查看的页面。默认为 False

is_section: bool = False 类属性 实例属性

表示导航对象是“部分”对象。对于页面对象,始终为 False

is_page: bool = True 类属性 实例属性

表示导航对象是“页面”对象。对于页面对象,始终为 True

表示导航对象是“链接”对象。对于页面对象,始终为 False

目录中的单个条目。

title: str 实例属性

项目的文本,以 HTML 格式。

url: str 属性

指向项目的 URL 的哈希片段。

level: int 实例属性

项目的零基级别。

children: list[AnchorLink] 实例属性

任何子项目的可迭代对象。

包含在 nav 模板变量中的导航对象可能是 section 对象、page 对象和 link 对象之一。虽然 section 对象可能包含嵌套的导航对象,但页面和链接则不会。

Page 对象是用于当前 page 的完整页面对象,具有所有相同的可用属性。Section 和 Link 对象包含如下定义的属性子集

Section

section 导航对象定义了导航中的一个命名部分,并包含一个子导航对象的列表。请注意,部分不包含 URL,也不属于任何类型的链接。但是,默认情况下,MkDocs 会将索引页面排序到顶部,如果主题选择这样做,则第一个子级可能被用作部分的 URL。

基础:StructureItem

以下属性在 section 对象上可用

title: str 实例属性

部分的标题。

parent: Section | None = None 类属性 实例属性

站点导航中项目的直接父级。如果在顶层,则为 None

children: list[StructureItem] 实例属性

所有子导航对象的迭代对象。子级可能包括嵌套的部分、页面和链接。

active: bool 属性 可写

当为 True 时,表示此部分的子页面是当前页面,可用于将部分突出显示为当前查看的部分。默认为 False

is_section: bool = True 类属性 实例属性

指示导航对象是“节”对象。对于节对象始终为True

is_page: bool = False 类属性 实例属性

指示导航对象是“页面”对象。对于节对象始终为False

指示导航对象是“链接”对象。对于节对象始终为False

一个链接导航对象包含一个指向非内部MkDocs页面的链接。

基础:StructureItem

以下属性在链接对象上可用

title: str 实例属性

链接的标题。这通常用作链接的标签。

url: str 实例属性

链接指向的URL。该URL应始终为绝对URL,并且不需要添加base_url前缀。

parent: Section | None = None 类属性 实例属性

站点导航中项目的直接父级。如果在顶层,则为 None

children: None = None 类属性 实例属性

链接不包含子项,该属性始终为None

active: bool = False 类属性 实例属性

外部链接不能为“活动”,该属性始终为False

is_section: bool = False 类属性 实例属性

指示导航对象是“节”对象。对于链接对象始终为False

is_page: bool = False 类属性 实例属性

指示导航对象是“页面”对象。对于链接对象始终为False

指示导航对象是“链接”对象。对于链接对象始终为True

额外上下文

可以使用extra配置选项将其他变量传递给模板。这是一组键值对,可以使自定义模板更加灵活。

例如,这可以用于在所有页面上包含项目版本以及与项目相关的链接列表。这可以通过以下extra配置实现

extra:
  version: 0.13.0
  links:
    - https://github.com/mkdocs
    - https://docs.readthedocs.org/en/latest/builds.html#mkdocs
    - https://mkdocs.pythonlang.cn/

然后在自定义主题中使用以下HTML显示。

{{ config.extra.version }}

{% if config.extra.links %}
  <ul>
  {% for link in config.extra.links %}
      <li>{{ link }}</li>
  {% endfor %}
  </ul>
{% endif %}

模板过滤器

除了Jinja的默认过滤器之外,以下自定义过滤器可用于MkDocs模板

url

规范化URL。绝对URL直接通过。如果URL是相对的并且模板上下文包含页面对象,则返回相对于页面对象的URL。否则,返回带有base_url前缀的URL。

<a href="{{ page.url|url }}">{{ page.title }}</a>

tojson

安全地将Python对象转换为JavaScript脚本中的值。

<script>
    var mkdocs_page_name = {{ page.title|tojson|safe }};
</script>

script_tag

1.5版本新增

extra_javascript中的项目转换为<script>标签,该标签会考虑此配置的所有自定义项,并且具有等效的|url行为内置。

请查看上面的基本示例中的用法

搜索和主题

从MkDocs版本0.17开始,通过search插件向MkDocs添加了客户端搜索支持。主题需要提供一些内容才能使插件与主题协同工作。

虽然search插件默认情况下处于活动状态,但用户可以禁用该插件,并且主题应对此进行考虑。建议主题模板使用插件检查来包装搜索特定标记

{% if 'search' in config.plugins %}
    search stuff here...
{% endif %}

在最基本的功能下,搜索插件只提供一个索引文件,它只是一个包含所有页面内容的JSON文件。主题需要在客户端实现自己的搜索功能。但是,使用一些设置和必要的模板,插件可以基于lunr.js提供完整的客户端搜索工具。

需要将以下HTML添加到主题中,以便提供的JavaScript能够正确加载搜索脚本并从当前页面创建到搜索结果的相对链接。

<script>var base_url = {{ base_url|tojson }};</script>

通过正确配置的设置,模板中的以下HTML将为您的主题添加完整的搜索实现。

<h1 id="search">Search Results</h1>

<form action="search.html">
  <input name="q" id="mkdocs-search-query" type="text" >
</form>

<div id="mkdocs-search-results">
  Sorry, page not found.
</div>

插件中的JavaScript通过查找上述HTML中使用的特定ID来工作。用户输入搜索查询的表单输入必须使用id="mkdocs-search-query"标识,结果将放置在其中的div必须使用id="mkdocs-search-results"标识。

该插件支持在主题的配置文件mkdocs_theme.yml中设置以下选项

include_search_page

确定搜索插件是否期望主题通过位于search/search.html的模板提供一个专门的搜索页面。

include_search_page设置为true时,搜索模板将被构建并可用于search/search.html。这种方法被readthedocs主题使用。

include_search_page设置为false或未定义时,期望主题提供一些其他机制来显示搜索结果。例如,mkdocs主题通过模态在任何页面上显示结果。

search_index_only

确定搜索插件是否应该只生成搜索索引或完整的搜索解决方案。

search_index_only设置为false时,搜索插件会修改Jinja环境,通过添加自己的templates目录(优先级低于主题)并将其脚本添加到extra_javascript配置设置中。

search_index_only设置为true或未定义时,搜索插件不会修改Jinja环境。使用提供的索引文件的完整解决方案由主题负责。

搜索索引写入site_dirsearch/search_index.json的JSON文件。文件中包含的JSON对象最多可以包含三个对象。

{
    config: {...},
    docs: [...],
    index: {...}
}

如果存在,config对象包含用户在mkdocs.yml配置文件的plugings.search下为插件定义的配置选项的键值对。config对象是MkDocs版本1.0中的新增内容。

docs对象包含一个文档对象列表。每个文档对象都由一个location(URL)、一个title和一个text组成,这些可以用来创建搜索索引和/或显示搜索结果。

如果存在,index对象包含一个预构建的索引,它可以为大型网站提供性能改进。请注意,只有在用户明确启用prebuild_index配置选项时才会创建预构建索引。主题应该期望索引不存在,但可以选择在索引可用时使用索引。index对象是MkDocs版本1.0中的新增内容。

打包主题

MkDocs使用Python打包来分发主题。这有一些要求。

要查看包含一个主题的包的示例,请参阅MkDocs Bootstrap主题,要查看包含多个主题的包,请参阅MkDocs Bootswatch主题.

注意

打包主题并非严格必要,因为整个主题可以包含在custom_dir中。如果您创建了一个“一次性主题”,那就足够了。但是,如果您打算将您的主题分发给其他人使用,打包主题会有一些优点。通过打包主题,您的用户可以更轻松地安装主题,他们可以依赖于定义的默认配置,然后他们可以利用custom_dir对您的主题进行调整,使其更适合他们的需求。

包布局

建议为主题使用以下布局。顶层目录中的两个文件分别为MANIFEST.insetup.py,它们位于包含空__init__.py文件、主题配置文件(mkdocs_theme.yml)以及您的模板和媒体文件的主题目录旁边。

.
|-- MANIFEST.in
|-- theme_name
|   |-- __init__.py
|   |-- mkdocs_theme.yml
|   |-- main.html
|   |-- styles.css
`-- setup.py

MANIFEST.in文件应包含以下内容,但更新theme_name并将任何额外的文件扩展名添加到包含项中。

recursive-include theme_name *.ico *.js *.css *.png *.html *.eot *.svg *.ttf *.woff
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

setup.py应包含以下文本,并进行如下修改。

from setuptools import setup, find_packages

VERSION = '0.0.1'

setup(
    name="mkdocs-themename",
    version=VERSION,
    url='',
    license='',
    description='',
    author='',
    author_email='',
    packages=find_packages(),
    include_package_data=True,
    entry_points={
        'mkdocs.themes': [
            'themename = theme_name',
        ]
    },
    zip_safe=False
)

填写URL、许可证、描述、作者和作者电子邮件地址。

名称应遵循约定mkdocs-themename(如mkdocs-bootstrapmkdocs-bootswatch),以MkDocs开头,使用连字符分隔单词,并包含您的主题的名称。

文件的大部分其他部分可以保持不变。我们需要更改的最后一部分是entry_points。这就是MkDocs找到您包含在包中的主题的方式。左边的名称是用户将在他们的mkdocs.yml中使用的名称,右边的名称是包含您的主题文件的目录。

您在本节开头创建的包含main.html文件的目录应包含所有其他主题文件。最低要求是它包含主题的main.html。它必须包含一个__init__.py文件,该文件应为空,此文件告诉Python该目录是一个包。

主题配置

打包的主题需要包含一个名为mkdocs_theme.yml的配置文件,该文件放置在模板文件的根目录中。该文件应包含主题的默认配置选项。但是,如果主题不提供任何配置选项,则仍然需要该文件,并且可以留空。未打包的主题不需要mkdocs_theme.yml文件,因为该文件不会从theme.custom_dir加载。

主题作者可以自由定义任何认为必要的任意选项,这些选项将在模板中提供以控制行为。例如,主题可能希望使侧边栏可选,并在mkdocs_theme.yml文件中包含以下内容

show_sidebar: true

然后在模板中,可以引用该配置选项

{% if config.theme.show_sidebar %}
<div id="sidebar">...</div>
{% endif %}

用户可以在其项目的mkdocs.yml配置文件中覆盖默认值

theme:
  name: themename
  show_sidebar: false

除了主题定义的任意选项之外,MkDocs 还定义了一些特殊选项,这些选项会改变其行为

locale

此选项反映了同名主题的主题配置选项。如果此值未在mkdocs_theme.yml文件中定义,并且用户未在mkdocs.yml中设置它,则它将默认为en(英语)。该值应与主题提供的文本(如“下一个”和“上一个”链接)中使用的语言匹配,并应作为<html>标签的lang属性的值使用。有关更多信息,请参阅支持主题本地化/翻译

请注意,在配置验证期间,提供的字符串将转换为Locale对象。该对象包含Locale.languageLocale.territory属性,并将从模板中解析为字符串。因此,以下操作将正常工作

<html lang="{ config.theme.locale }">

如果区域设置设置为fr_CA(加拿大法语),则上述模板将呈现为

<html lang="fr_CA">

如果您不想包含区域属性,则直接引用language属性

<html lang="{ config.theme.locale.language }">

这将呈现为

<html lang="fr">

static_templates

此选项反映了同名主题的主题配置选项,并允许主题设置一些默认值。请注意,虽然用户可以将模板添加到此列表中,但用户不能删除主题配置中包含的模板。

extends

定义此主题继承的父主题。该值应该是父主题的字符串名称。正常的Jinja 继承规则适用。

插件也可以定义一些选项,允许主题告知插件它期望的插件选项集。有关您可能希望在主题中支持的任何插件的文档,请参阅相关文档。

分发主题

有了上述更改,您的主题现在应该可以安装了。这可以使用 pip 完成,如果您仍在与 setup.py 相同的目录中,则使用pip install .

大多数 Python 包,包括 MkDocs,都在 PyPI 上分发。要做到这一点,您应该运行以下命令。

python setup.py register

如果您还没有设置帐户,系统将提示您创建一个。

有关更详细的指南,请参阅官方 Python 打包文档,了解打包和分发项目

支持主题本地化/翻译

虽然内置主题提供了对本地化/翻译模板的支持,但自定义主题和第三方主题可能选择不提供。无论如何,theme配置选项的locale设置始终存在,并且其他系统部分依赖于它。因此,建议所有第三方主题使用相同的设置来指定语言,无论它们使用什么翻译系统。这样,无论用户选择哪个主题,他们都会体验到一致的行为。

管理翻译的方法取决于主题开发人员。但是,如果主题开发人员选择使用内置主题使用的相同机制,则以下部分概述了如何启用并使用 MkDocs 使用的相同命令。

使用本地化/翻译命令

警告

由于pybabel 默认情况下未安装,并且大多数用户不会安装 pybabel,因此主题开发人员和/或翻译人员应确保已安装必要的依赖项(使用pip install 'mkdocs[i18n]'),以便命令可用。

翻译命令应该从主题工作树的根目录中调用。

有关 MkDocs 用于翻译内置主题的工作流程的概述,请参阅贡献指南的相应部分翻译指南

示例自定义主题本地化/翻译工作流程

注意

如果您的主题继承自已提供翻译目录的现有主题,则您的主题翻译将在 MkDocs 构建期间与父主题的翻译合并。

这意味着您只需要专注于添加的翻译。但是,您仍然可以从父主题的翻译中受益。同时,您可以覆盖任何父主题的翻译!

假设您正在使用您自己的mkdocs-basic-theme分支,并且想要为它添加翻译。

通过在您的 HTML 源代码中使用{% trans %}{% endtrans %}将文本包装起来来编辑模板,如下所示

--- a/basic_theme/base.html
+++ b/basic_theme/base.html
@@ -88,7 +88,7 @@

 <body>

-  <h1>This is an example theme for MkDocs.</h1>
+  <h1>{% trans %}This is an example theme for MkDocs.{% endtrans %}</h1>

   <p>
     It is designed to be read by looking at the theme HTML which is heavily

然后,您可以像往常一样遵循翻译指南来使您的翻译运行。

将翻译打包到您的主题中

虽然extract_messages命令创建的 Portable Object Template (pot) 文件以及init_catalogupdate_catalog命令创建的 Portable Object (po) 文件对于创建和编辑翻译很有用,但它们不会被 MkDocs 直接使用,也不需要包含在主题的打包版本中。当 MkDocs 构建具有翻译的站点时,它只使用指定区域设置的二进制mo文件。因此,当打包主题时,请确保使用MANIFEST.in文件或其他方式将其包含在“轮子”中。

然后,在构建 Python 包之前,您需要确保每个区域设置的二进制mo文件都是最新的,为此,请针对每个区域设置运行compile_catalog命令。MkDocs 期望二进制mo文件位于locales/<locale>/LC_MESSAGES/messages.mocompile_catalog命令会自动为您执行此操作。有关详细信息,请参阅测试主题翻译

注意

正如我们的翻译指南中所述,MkDocs 项目已选择在我们的代码存储库中包含potpo文件,但不包含mo文件。这要求我们始终在打包新版本之前运行compile_catalog,无论是否对翻译进行了更改。但是,您可以为您的主题选择另一种工作流程。至少,您需要确保在每个版本中都包含最新的mo文件,并位于正确的位置。但是,如果您选择这样做,您可以使用不同的过程来生成这些mo文件。