Skip to content

导航、作者和分页

Blog 插件提供了博客风格的导航,默认情况下有一个反向时间顺序的索引页面和按年份组织的档案。本教程展示了如何配置默认导航的细节,配置作者,并使用类别和 Tags plugin 添加更多导航选项。

所需时间: 通常为 30 分钟

集成导航

到目前为止,您已经让 Blog 插件和 MkDocs 处理导航。对于某些用例,这可能已经足够,仅需在 mkdocs.yml 中不声明 nav 部分即可。

然而,您可能希望将博客与您在配置的 nav 部分中定义的其他内容和导航结构集成。在这种情况下,您需要提供一个位置,让 Blog 插件将博客导航附加到其余导航结构中。

与站点导航集成

将以下内容添加到您的 mkdocs.yml 中,以查看 Blog 插件如何将博客导航与整体导航结构集成。请注意,此时您只需指定博客的索引页面,其路径必须与 blog_dir 设置相匹配,默认值为 blog

nav:
  - Home: index.md
  - Install: install.md
  - Usage: usage.md
  - Blog:
     - blog/index.md

您会注意到“Blog”在导航结构中重复出现。为了避免这种情况,您可以使用 navigation.indexes 功能,使博客索引成为博客的部分索引页面:

theme:
  name: material
  features:
    - navigation.indexes

独立博客

如果您需要的是一个独立的博客,而不是与更大网站集成的博客,可以通过使用 blog_dir 配置选项来实现。要了解如何做到这一点,请参见 设置博客。本教程的其余部分假设您正在将博客与更广泛的网站集成。

添加页面

您可以通过将额外页面放入 docs/blog(并将其添加到导航中)来向博客部分添加额外页面。这些页面之后,博客档案将被添加到导航中。

配置档案

默认情况下,博客档案仅按年份列出帖子。如果您想按月份添加列表,可以配置档案的日期格式。

按月份组织帖子

将以下内容添加到您的 mkdocs.yml 中,以获取带有月份名称的列表(以主题选项中选择的语言显示):

- blog:
    archive_date_format: MMMM yyyy

如果您不想要完整的月份名称,可以将日期配置为 MM/yyyy,例如。

如果您想添加日期,可以为其添加占位符。例如,要获取美式风格的输出,可以将其设置为 MM/dd/yyyy。为了使插件按完整日期对博客帖子进行排序,您还需要将 archive_url_date_format 设置为包含月份和日期,因此也将其设置为 MM/dd/yyyy

使用类别

类别是一种使博客帖子按主题可访问的方式,同时在每个类别列表中保留基于时间顺序的导航结构。当您可以将帖子分类到有限的一组不重叠的类别中时,请使用它们。

类别出现在主导航中,因此可以直接从那里访问。这意味着类别相对较少,否则您的主导航中的 categories 部分将变得过于拥挤。

添加类别

通过将其添加到页面头部,为您的第一篇博客帖子添加一个类别:

---
date: 2023-12-31
updated: 2024-01-02
categories:
  - Holidays
---

现在,博客帖子已被分类,Holidays 出现在主导航的 Categories 下,博客帖子出现在该类别的索引页面中。

单一或多个类别?

虽然传统上博客帖子只属于一个类别,但 Material for MkDocs 实际上允许您分配多个类别。虽然这给您提供了一定的自由度,但您可能不应过多使用,尤其是因为您可以使用标签来处理多个分类。我们将在下一步中介绍它们。

Material 允许您控制博客作者可以使用哪些类别。您在 mkdocs.yml 中声明它们。这样,您可以确保每个人都遵循约定的类别,并且插件可以检测拼写错误。

控制您的类别

在 Blog 插件的配置中添加 categories_allowed 条目,包含 "Holidays" 和 "News":

plugins:
  - search
  - blog:
      archive_date_format: MMMM yyyy
      categories_allowed:
        - Holidays
        - News

现在,当您向博客帖子添加一个不匹配这两个类别的类别时,您应该会收到构建错误。

使用标签

Tags plugin 提供了另一种对博客帖子进行分类的方法,使其独立于主导航结构可访问。标签对于使相关内容易于发现非常有用,即使它位于导航层次的不同部分。

您可能有像这样的教程,以及更全面的设置指南和参考文档。将相同的标签添加到这三者中显示它们是相关的。正如您将看到的,可以从带标签的页面导航到标签索引,然后从那里导航到其他带有相同标签的页面。

启用插件并添加标签

首先,您需要将插件添加到您的 mkdocs.yml 中:

plugins:
  - search
  - blog:
      archive_date_format: MMMM yyyy
      categories_allowed:
        - Holidays
        - News
  - tags

完成后,您可以在页面头部为帖子添加标签:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
authors:
  - material
categories:
  - Holidays
tags:
  - new year
  - hogmanay
  - festive season
---

您应该会看到您在帖子顶部定义的标签。然而,目前为止就是这样。虽然博客插件会自动为类别创建索引页面,但标签插件并不会为标签做同样的事情。这是因为标签插件并不特定于博客。您可以将其用于任何站点内容,因此标签索引应该放在哪里并不明显。

您可以使用 Material for MkDocs 的公共版本配置基本标签索引。Insider 版本当然也支持这一点,但还提供了一种替代索引机制,允许任意数量的标签索引、范围列表、影子标签、嵌套标签等等。

添加标签索引

要使用公共版本配置标签索引,请在标签插件的配置中添加 tags_file 条目,并在 nav 部分中配置它。记得在现有的 tags 条目末尾添加冒号。

plugins:
    - search
    - blog:
        archive_date_format: MMMM yyyy
        categories_allowed:
            - Holidays
            - News
    - tags:
        tags_file: blog/tags.md

nav:
    - Home: index.md
    - Install: install.md
    - Usage: usage.md
    - Blog:
        - blog/index.md
        - Tags: blog/tags.md

标签索引将附加到配置的页面,您现在应该在指定的位置创建该页面。

请注意,您可以将标签索引页面放置在主导航的任何位置,因此如果您在其他地方使用标签而不仅仅是在博客中,则可能希望将标签索引放在导航的博客部分之外。

要添加标签索引,您在 Markdown 文件中添加一个占位符,以告诉插件在该点插入索引。这意味着您可以在索引之前和之后添加内容。关键是,您可以在多个页面中添加占位符,每个页面都有配置,指定应在索引中显示哪些标签子集。

最简单的索引页面如下所示。将其创建在 docs/tags.md 下。

# 标签索引
<!-- material/tags -->

现在,您可能希望将博客的标签与您在页面其余部分使用的标签分开。您可以通过为标签索引分配作用域来实现这一点。在 docs/blog/tags.md 下放置以下内容:

# 博客的标签索引
<!-- material/tags { scope: true } -->

现在,您有两个索引页面:一个涵盖整个站点,另一个仅涵盖博客。将两者都添加到导航中:

nav:
    - Home: index.md
    - Tags: tags.md
    - Blog:
        - blog/index.md
        - blog/tags.md

Insider 版本中的标签插件是一个非常强大的工具,我们只能触及其可能性的表面。如果您希望在完成本教程的这一部分后进一步探索,请查看 标签插件参考

定义作者

如果您的博客有多个作者,您可能希望为每篇博客帖子识别作者。博客插件允许您创建一个包含作者信息的文件,然后在页面头部引用特定帖子的作者。

创建作者信息

创建一个文件 docs/blog/.authors.yml,内容如下:

authors:
  team:
    name: Team
    description: Creator
    avatar: https://simpleicons.org/icons/materialformkdocs.svg
  squidfunk:
    name: Martin Donath
    description: Creator
    avatar: https://github.com/squidfunk.png

然后在第一篇帖子的头部添加一行:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
authors:
  - team
---

请注意,authors 是一个列表,因此您可以指定多个作者。

您可以创建自定义作者索引页面,以突出作者的贡献并提供有关他们的更多信息。

添加作者页面

首先,您需要在 mkdocs.yml 中启用作者资料:

plugins:
  - search
  - blog:
      archive_date_format: MMMM yyyy
      categories_allowed:
          - Holidays
          - News
      authors_profiles: true

检查您的博客,查看主导航中是否有一个额外条目,列出作者及其贡献,位于 archivecategories 旁边。

要自定义作者页面,您可以创建一个覆盖默认生成页面的页面。首先,创建一个 author 目录,资料页面将存放在其中:

docs
├── blog
│   ├── author
│   ├── index.md
│   └── posts
│       ├── draft.md
│       └── myfirst.md
└── index.md

然后创建页面 docs/blog/author/team.md

# Material 团队

一小群致力于让编写文档变得简单,甚至有趣的人!以下是我们博客中讨论的一些内容:

如您所见,作者索引会附加到您在 Markdown 文件中编写的内容之后。

分页

一旦您的博客开始增长,您可能不希望关注每页显示的帖子数量。默认情况下,插件在索引页面上显示最多 10 篇帖子。您可以为主索引、档案索引页面和类别索引页面单独更改此数字。

更改分页

添加五篇博客帖子,然后设置分页设置仅显示每页五篇:

- blog:
    archive_date_format: MMMM yyyy
    categories_allowed:
        - Holidays
        - News
    authors_profiles: true
    pagination_per_page: 5

您会看到档案和类别页面的分页设置是从您添加的设置中继承的。如果您希望不同的索引页面有不同的设置,可以分别指定每个设置:

- blog:
    archive_date_format: MMMM yyyy
    categories_allowed:
        - Holidays
        - News
    authors_profiles: true
    pagination_per_page: 5
    archive_pagination_per_page: 10
    categories_pagination_per_page: 10

博客目录

一旦您有足够数量的帖子,您可能希望启用生成博客索引页面目录的功能,让读者能够快速浏览每个页面的内容,找到他们感兴趣的内容,而无需滚动(假设每页的帖子数量不太大)。

启用目录功能

要为博客索引页面生成目录,请将以下内容添加到博客插件的配置中:

- blog:
    blog_toc: true
    archive_date_format: MMMM yyyy
    # ...

自定义别名

如果由于某种原因,您对 Material for MkDocs 将标题转换为别名的方式不满意,您可以创建自己的别名函数,或者手动为特定帖子定义别名。

别名函数

要定义您自己的别名函数,您需要编写一个 Python 函数,该函数根据配置中的附加参数将文本转换为别名。您还需要编写一个返回该函数的函数。

假设您想定义两个别名函数,以便可以在它们之间切换。第一个返回的别名类似于默认别名函数生成的结果。第二个将结果切分为单词,并基于最多五个单词返回一个别名:

import re, functools, unicodedata

RE_HTML_TAGS = re.compile(r'</?[^>]*>', re.UNICODE)
RE_INVALID_SLUG_CHAR = re.compile(r'[^\w\- ]', re.UNICODE)
RE_WHITESPACE = re.compile(r'\s', re.UNICODE)

def _make_slug(text, sep, **kwargs):
    slug = unicodedata.normalize('NFC', text)
    slug = RE_HTML_TAGS.sub('', slug)
    slug = RE_INVALID_SLUG_CHAR.sub('', slug)
    slug = slug.strip().lower()
    slug = RE_WHITESPACE.sub(sep, slug)
    return slug

def _make_slug_short(text, sep, **kwargs):
    words = _make_slug(text, sep, **kwargs).split(sep)
    return sep.join(words[:5])

def slugify(**kwargs):
    if 'short' in kwargs and kwargs['short']:
        return functools.partial(_make_slug_short, **kwargs)
    return functools.partial(_make_slug, **kwargs)

将此代码保存在 ext/slugs.py 中,并添加一个(空的)__init__.py 文件以指示该目录是一个模块。现在,您可以像这样配置您的自定义别名代码:

plugins:
- blog:
    # 其他条目省略
    post_slugify: !!python/object/apply:ext.slugs.slugify
      kwds:
        short: true

将博客帖子的标题更改为超过五个单词,并观察别名函数如何缩短 URL。将 short 属性更改为 false,您可以再次关闭此功能。

如果您希望仅对单个博客帖子影响别名,可以通过在帖子的头部指定它来手动定义。请注意,这应作为最后的选择。为每个帖子手动指定自定义别名将是繁琐的。

手动定义别名

如果,例如,您希望别名为 'ny-eve' 而不是稍长的 'happy-new-years-eve',您可以添加以下内容:

---
date:
  created: 2023-12-31
  updated: 2024-01-02
readtime: 15
pin: true
slug: ny-eve
---

该帖子的 URL 现在应为 http://localhost:8000/blog/2023/01/31/ny-eve/

接下来是什么?

您可能希望通过允许人们订阅 RSS 源、提供社交媒体个人资料链接、提供分享和点赞按钮或设置评论系统来增加与博客的互动。 互动和传播教程 将指导您设置这些功能。