Как добавить постоянные ссылки на узлы дерева в навигационном файле Markdown (mkdocs.yml)?

Навигационный файл 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/bottomlevelcat или example.net/docs/guides/toplevelcat#bottomlevelcat неважно, как именно будут организованы ссылки и генерируются ли они автоматически или задаются вручную

ссылка может вести на индексную страницу со всеми руководствами, относящимися к категории ИЛИ просто отображать корневую страницу mysite.net/docs/guides/ с требуемой развернутой категорией


4
1 595
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 }}), вместо этого мы проверяем, является ли первый дочерний элемент индексным файлом, и, если да, вместо этого отображаем ссылку на индексную страницу. Конечно, мы включаем запасной вариант для тех случаев, когда нет index.

{% 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, который каждый уровень вызывает рекурсивно.

Также следует отметить, что вам не нужно разрабатывать полную пользовательскую тему. Возможно, вы захотите вместо переопределить блок шаблона существующей темы использовать собственную навигацию.


Я реализовал плагин для этой функциональности, «mkdocs-раздел-индекс», и он работает аналогично что @Waylan описывает — или даже больше похож на отброшенный запрос на включение # 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

Это дает вам навигацию следующим образом:

Для меня имеет смысл, что эта функция не может быть включена по умолчанию, но плагин как способ подписки кажется вполне подходящим.