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

时间:2019-02-08 16:41:48

标签: markdown mkdocs

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

我对Markdown和mkdocs很陌生;我在Google上进行了彻底的搜索以获取解决方案,但没有找到解决方案。

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/bottomlevelcat 要么 example.net/docs/guides/toplevelcat#bottomlevelcat 链接的组织方式,自动生成还是手动预设都无所谓

该链接可能会导致一个索引页面,其中所有手册都属于该类别,或者仅显示根目录 mysite.net/docs/guides / 并扩展了所需的类别

2 个答案:

答案 0 :(得分:1)

MkDocs目前不支持此功能,但是custom theme可能可以实现。

#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 %} 

通过解释,以上内容只是文档中example的略微修改版本。在原始({{ 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 documentation在这里可能会有所帮助。

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

还要注意的是,您不需要开发完整的自定义主题。您可能希望改用override a template block您自己的自定义导航的现有主题。

答案 1 :(得分:0)

我已经为此功能实现了一个插件“ mkdocs-section-index ”,该插件的工作方式类似于what @Waylan describes,或者实际上更类似于the dropped 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

这给你带来了这样的导航:

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