如何向 Markdown 导航文件 (mkdocs.yml) 中的树节点添加永久链接?

Cyb*_*ead 5 markdown mkdocs

我正在使用的 mkdocs.yml nav 文件包含手册网站的层次结构树,其中包含内容文章所属的多个类别和子类别;该树绝对是虚拟的,不基于文件夹结构/网站路径。我正在寻找一种为每个树节点(类别)生成永久链接的方法。如果 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
Run Code Online (Sandbox Code Playgroud)

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

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

Way*_*lan 3

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'
Run Code Online (Sandbox Code Playgroud)

请注意,每个部分都包含一个唯一的索引文件。当然,索引文件必须命名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 %} 
Run Code Online (Sandbox Code Playgroud)

作为解释,上面只是文档中示例的稍微修改的版本。在原始 ( {{ 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 %}
Run Code Online (Sandbox Code Playgroud)

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

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

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