4

我正在使用的 mkdocs.yml 导航文件包括一个手册网站的层次结构树,其中包含内容文章所属的多个类别和子类别;树是绝对虚拟的,而不是基于文件夹结构/网站路径。我正在寻找一种为每个树的节点(类别)生成永久链接的方法。如果 Markdown 或其扩展无法做到这一点,那么也许可以使用 html/css 元素。

我对 Markdown 和 mkdocs 很陌生;我彻底搜索了一个解决方案,但没有找到一个。

site_name: My Site
site_dir: docs/guides/
site_url: http://example.net/
docs_dir: 'src'
nav:
  - 'TOP LEVEL CATEGORY':
    - 'BOTTOM LEVEL CATEGORY':
         - Manual 1: 'manuals/Manual1.md'
         - Manual 2: 'manuals/Manual2.md'
    - 'BOTTOM LEVEL 2':
{...}
  - 'TOP LEVEL CATEGORY 2':
{...}

markdown_extensions:
    - smarty
    - toc:
        permalink: True
        separator: "_"
    - sane_lists
    - tables
    - meta
    - fenced_code
    - admonition
    - footnotes

构建的具有可扩展节点的虚拟分层树是可以的,但我确实需要为每个类别和子类别生成永久链接,例如 example.net/docs/guides/toplevelcat/bottomlevelcatexample.net/docs/guides/toplevelcat# bottomlevelcat 链接的组织方式以及它们是自动生成还是手动预设都无关紧要

该链接可能会指向一个索引页面,其中包含属于该类别的所有手册,或者仅显示根mysite.net/docs/guides/页面并展开所需的类别

4

2 回答 2

2

目前 MkDocs 不支持此功能,但可以使用自定义主题

#1042中,您可以找到解决方案的尝试,但由于多种原因最终被拒绝。也就是说,您应该能够使用自定义主题来模拟类似的东西。

MkDocs 不关心文件的结构是否nav匹配任何实际的文件结构。因此,您可以随意安排嵌套结构。只需确保任何“节”的第一个子项指向索引文件即可。也许是这样的:

nav:
  - 'TOP LEVEL CATEGORY':
    - 'toplevel1/index.md'
    - 'BOTTOM LEVEL CATEGORY':
         - 'bottomlevel1/index.md'
         - Manual 1: 'manuals/Manual1.md'
         - Manual 2: 'manuals/Manual2.md'
    - 'BOTTOM LEVEL 2':
         - 'bottomlevel2/index.md'

请注意,每个部分都包含一个唯一的索引文件。当然索引文件必须被命名index.md,所以唯一的方法是使它们唯一的方法是每个文件都在一个唯一的子目录中。另请注意,没有为索引页分配标题。大概会使用章节标题。

然后在您的主题模板中,您需要检查子项,如果第一个子项是索引,则将其用作该部分的链接。然后在遍历孩子时,一定要跳过嵌套级别中的索引。

也许是这样的:

{% if nav|length>1 %}
    <ul>
    {% for nav_item in nav %}
        {% if nav_item.children %}
            <li>{% if nav_item.children[0].is_index %}
                    <a href="{{ nav_item.children[0].url|url }}">{{ nav_item.title }}</a>
                {% else %}
                    {{ nav_item.title }}
                {% endif %}
                <ul>
                {% for nav_item in nav_item.children[1:] %}
                    <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 %} 

作为解释,以上只是文档中示例的略微修改版本。在原始 ( {{ nav_item.title }}) 中显示部分标题的地方,我们改为检查第一个子文件是否是索引文件,如果是,则显示指向索引页面的链接。当然,对于那些没有索引的情况,我们包括一个备用。

{% if nav_item.children[0].is_index %}
    <a href="{{ nav_item.children[0].url|url }}">{{ nav_item.title }}</a>
{% else %}
    {{ nav_item.title }}
{% endif %}

然后在单步执行子项时,我们要避免包含索引文件。我{% for nav_item in nav_item.children[1:] %}在我的示例中使用([1:]切片列表以排除第一项),但假设始终存在索引文件。其他一些解决方案可能会更好,并留给读者作为练习。Jinja 文档在这里可能会有所帮助。

还要注意,上面的模板只考虑了一层嵌套。需要开发更复杂的解决方案来处理多个嵌套级别。例如,您可能想要定义一个 Jinja 宏,每个级别都递归调用该宏。

另外值得注意的是,您不需要开发完整的自定义主题。您可能想要覆盖您自己的自定义导航的现有主题的模板块。

于 2019-02-08T19:04:33.557 回答
1

我已经为这个功能实现了一个插件,“ mkdocs-section-index ”,它的工作方式与@Waylan 描述的类似——或者实际上更类似于drop pull request #1042,因为大部分逻辑都在主题之外/模板。带有链接的特殊部分被明确地放入导航中并以主题形式呈现,因此它不需要查找和排除这个“第一个孩子”本身。

mkdocs.yml

plugins:
  - section-index
nav:
  - Frob: index.md
  - Baz: baz.md
  - Borgs:
    - borgs/index.md
    - Bar: borgs/bar.md
    - Foo: borgs/foo.md

这会给你一个像这样的导航:

对我来说,默认情况下不能包含此功能是有道理的,但是作为一种选择加入的插件似乎非常好。

于 2020-11-28T20:39:01.090 回答