Руководство по созданию контента

Введение

Исходный код документации создается в формате Markdown, с расширениями YFM (Yandex Flavoured Markdown). Эффективным способом быстро изучить эти форматы является знакомство с исходным кодом имеющейся документации YDB.

Кроме описанных здесь формальных правил, всегда действует неявное дополнение: если на какую-то тему правило формально не описано, необходимо посмотреть как уже сделано ранее в других местах документации, и сделать по аналогии.

Также нужно помнить о том, что из любых правил бывают исключения, и их невозможно описать все.

Ядро и кастомизация документации

OpenSource документация по YDB поддерживает создание на её базе кастомизированных документаций для enterprise-окружений, где эксплуатируется YDB, или для облачных провайдеров, предоставляющих сервис YDB в своих экосистемах.

При добавлении контента вам придется в первую очередь выбрать куда его добавлять: в OpenSource ядро, или в какую-либо кастомизацию. Общая рекомендация - добавлять контент в OpenSource блок таким образом, чтобы он мог читаться в разных контекстах без необходимости его специфичной адаптации. Только когда это сделать не удается, или размещение в OpenSource ядре какого-то контента явно запрещено (например, ссылок на ресурсы интранет в enterprise-контексте), можно переходить к добавлению контента в исходный код кастомизации документации.

В тех разделах, где требования отличаются для базового контента и кастомизации, приведены две соответствующих закладки:

  • Core: ядро любой документации -- базовый контент
  • Overlay: накладываемый поверх ядра контент, адаптирующий его к кастомной сборке

Весь контент OpenSource сборки входит в состав ядра, и при его сборке применяется нулевая кастомизация, поэтому при его изменениях вам потребуется только закладка "Core".

Директории

Базовая структура директорий исходного кода основывается на тематике контента, а не типе файлов или их технической роли при сборке. Технические файлы и директории размещаются внутри тематических.

Статья "Обзор"

Каждая тематическая директория обязана содержать статью "Обзор" с именем файла index.md. В статье "Обзор":

  • Описывается о чем рассказывают статьи в данной директории
  • Может даваться перечень ссылок на все или отдельные наиболее важные статьи
  • Может даваться перечень ссылок "Смотрите также" на связанные другие статьи или разделы

Наличие статьи "Обзор" позволяет ссылаться на директорию в целом, а не на конкретную статью, а также без потери ссылочной целостности преобразовывать статьи в директории.

Статьи

Любая статья в базовой OpenSource документации создается в расчете на то, что она может быть расширена или скорректирована в кастомизированной документации, создаваемой на её основе. При этом, доработки базовой документации должны применяться в кастомизированной без ручного merge изменений контента, иначе ведение множества производных документаций становится очень трудозатратной задачей, а контроль полноты ручных адаптаций становится невозможным.

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

Вставляемые в статью блоки контента находятся в технической директории _includes, вложенной непосредственно в тематическую директорию.

Статья из одного блока

В простейшем случае статья состоит из одного блока, вставляемого директивой {% include ...%}:

article1.md:


{% include [article1.md](_includes/article1.md) %}

В директории _includes создается файл с контентом, одноименный с файлом статьи:

_includes/article1.md:

# Статья
Текст статьи.

Статья из нескольких блоков

Статья из одного блока позволяет при кастомизации документации добавить произвольный контент перед или после контента из базовой OpenSource документации. Этого может оказаться недостаточно, и тогда контент может быть разделен на большее количество блоков, позволяя при кастомизации документации как вставить произвольный контент между ними, так и исключить неприменимые блоки.

В этом случае, под статью создается одноименная директория внутри _includes. Например, если мы находимся внутри тематического каталога subject1, и хотим сделать статью article1 из двух блоков, то должны сделать три файла со следующим содержимым:

subject1/article1.md:


{% include [definition.md](_includes/article1/definition.md) %}

{% include [examples.md](_includes/article1/examples.md) %}

subject1/_includes/article1/definition.md:

# Статья документации
## Определение {#definition}
Статья документации -- это набор контента, раскрывающий определенную тему, интересную целевой аудитории.

subject1/_includes/article1/examples.md:

## Примеры {#examples}
- Кошки не похожи на людей. Кошки -- это кошки.
- Куст -- это совокупность веток, торчащих из одного места.

В кастомизации документации можно добавлять статьи, тематические каталоги, а также переопределять содержимое статей из core, размещая файл со статьей по тому же относительному пути внутри overlay, что он размещен внутри core.

При переопределении можно:

  • Добавить дополнительный контент в начало или конец статьи

    subject1/article1.md:

    
    {% include [article1](_includes/article1.md) %}
    
    В дополнение к базовым способам авторизации, в нашей компании применяется авторизация на основе нанотрубок.
    
  • Вставить дополнительный контент между директивами include

    subject1/article1.md:

    
    {% include [definition.md](_includes/article1/definition.md) %}
    
    В нашей компании объем данных в БД ограничен 150ZB.
    
    {% include [examples.md](_includes/article1/examples.md) %}
    
    Пример 2:
    The quick brown fox jumps over the lazy dog.
    
  • Убрать из сборки часть контента исходной статьи, удалив соответствующую директиву include

    subject1/article1.md:

    
    {% include [definition.md](_includes/article1/definition.md) %}
    
    В нашей компании объем данных в БД ограничен 150ZB.
    
    Пример:
    The quick brown fox jumps over the lazy dog.
    

При наличии множество блоков, и значительного количества добавляемого контента, может оказаться полезным его оформление также в виде блоков include, в созданной внутри тематической директории overlay поддиректории _includes. В этом случае, файл со статьей сохранит понятную структуру, охватываемую взглядом.

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

Особенности использования директивы include

  • Содержимое _includes не публикуется, поэтому на него бесполезно и запрещено ссылаться, оно может быть только included в cтатьи директивой {% include ... %}. К сожалению, при локальной сборке содержимое _includes остается доступным и работает, и ошибка проявляется только при развертывании документации на ферме.
  • Вокруг директивы {% include ... %} необходимо оставлять пустые строки, иначе она не будет исполнена при сборке.
  • В квадратных скобках нужно писать имя файла, чтобы было на что кликать при просмотре в default viewer github (который не понимает что такое include), и чтобы один include в нём визуально отличался от другого.
  • После {% в начале и перед %} в конце обязателен пробел, иначе include не будет исполнен при сборке.

Другие применения include

Директива {% include ... %} может технически применяться не только в целях поддержки создания производных документаций, но и просто для переиспользования контента в нескольких статьях. Однако, такое применение является нежелательным, так как появление одинакового контента в разных статьях запутывает пользователя, а редактирование included контента без понимания контекста, в котором он приводится, может легко приводить к потере смысла.

Допустимым и хорошим вариантом применения переиспользуемого контента является предоставление одной и той же информации в разных вариантах группировки в пределах одного контекста. Например, раздел FAQ содержит как статьи по темам, так и статью "Все вопросы по всем темам". Аналогично информация по ценам может приводиться как в специализированных статьях по каким-то тарифицируемым функциям, там и в общей статье прайс-листа.

Оглавление

Каждая статья должна быть упомянута в файле оглавления (TOC - Table Of Contents), иначе она не будет опубликована. Оглавление является основным инструментом начала навигации по документации, и размещается в левой части страниц сайта документации.

Внутри каждой тематической директории находятся два файла TOC:

  1. toc_i.yaml: содержит перечень статей для включения в оглавление, находящихся непосредственно в данной директории, за исключением особой обязательной статьи "Обзор", которая должна обязательно присутствовать в любом подразделе TOC:

    items:
    - name: Статья 1
      href: article1.md
    - name: Статья 2
      href: article2.md
    ...
    
  2. toc_p.yaml: содержит фиксированный контент, включающий статью "Обзор" и ссылку на toc_i.yaml:

    items:
    - name: Обзор
      href: index.md
    - include: { mode: link, path: toc_i.yaml }
    

Если у директории существуют дочерние директории, то в toc_i.yaml родительской директории явно указываются относительные ссылки на их toc_p.yaml:

...
- name: Подтема 1
  include: { mode: link, path: subject1/toc_p.yaml }
...

Непосредственно в директории core находится файл с корневым оглавлением toc_p.yaml, содержащий включение оглавлений toc_p.yaml из всех тематических директорий.

Если в кастомизированной документации не требуется изменения состава оглавления в некоторой тематической директории относительно базовой документации, то никаких файлов toc в overlay не создается. В сборку попадет файл toc из базовой документации.

При необходимости скорректировать состав статей в overlay включается файл toc_p.yaml, изначально скопированный из core, в котором можно добавить статьи или подразделы в начало или конец перечня статей из базовой документации:

items:
# Включение статьи "обзор" в начало перечня
- name: Обзор
  href: index.md
# Включение дополнительных пунктов перед пунктами из базовой документации
- name: Статья кастомизации 1 
  href: cust_article1.md
# Включение пунктов TOC базовой документации
- include: { mode: link, path: toc_i.yaml }
# Включение дополнительных пунктов после пунктов из базовой документации
- name: Дополнительный подраздел
  include: { mode: link, path: cust_subdir/toc_p.yaml }
- name: Статья кастомизации 2
  href: cust_article2.md

Заголовки разделов статей и якоря

Каждая статья должна в начале содержать заголовок первого уровня, обозначаемый одним символом #. Этот заголовок содержится в первом блоке контента.

Заголовки следующих уровней могут быть технически произвольным образом размещены в разных блоках контента, однако имеет размещать заголовки в начале блоков. Необходимо помнить, что в результате сборки статьи получится одна HTML-страница с заголовками.

Каждый заголовок второго и более уровня снабжается якорем (anchor), который может быть использован в ссылках вида host:path/article#anchor. При проходе по такой ссылке браузер прокрутит содержимое страницы до нужного места. Якоря задается в заголовке следующим образом:

## Заголовок {#anchor}

Допускается указание нескольких якорей, однако такое применение должно иметь под собой веские основания вроде сохранения совместимости с ранее существовавшими якорями при рефакторинге контента, например при объединении разделов:

## Заголовок объединенного раздела по теме X и Y {#X} {#Y} {#XY}

Указание якорей является расширением синтаксиса YFM по отношению к Markdown, поэтому общедоступные инструменты отображения Markdown (вроде preview в IDE) их не понимают.

Ссылки в тексте статей на другие статьи являются основным средством направления пользователя на другие темы, ассоциативно связанные с читаемым в данный момент контентом, подобно указателям на дороге. В идеале, разработчик документации должен понимать, каким образом пользователь доберется до нужной информации. Если некоторая статья никак не привязана ссылками к другим темам, а только размещена где-то в оглавлении в разделе "Прочее", то пользователь может никогда до неё не дойти, а мы будем регулярно отвечать на запросы в поддержку "так это же все описано вот тут, почему вы не читаете документацию"?

Никто и никогда не читает документацию как художественное произведение с начала до конца, пользователи всегда приходят для решения какой-то проблемы, они должны это решение найти, и ссылки между статьями являются основным инструментом навигации после того, как пользователь начал чтение, выбрав статью в TOC.

Ссылки бывают двух видов:

  1. На исходный код документации. Это всегда относительные ссылки на какой-то .md файл. При этом, чем больше в такой ссылке переходов "на уровень выше" или входов во вложенные директории, тем больше вероятность что документация плохо структурирована. В идеале, ссылки не должны выходить более чем на уровень вверх или на одну директорию вниз по иерархии:
    Для поддержания работоспособности котенка его [нужно кормить](../feeding/index.md).
    
  2. На внешние по отношению к документации ресурсы. Это fully-qualified URLs, в которых никогда не добавляется index:
    Хорошие корма для котов можно найти в [магазине Pushok](http://www.pushok.ru/catalog).
    

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

Существуют ситуации, когда URL ресурса имеет самостоятельную ценность, и должен быть отображен в документации, например, в случае публикации ссылок на репозиторий в github. В таких случаях его необходимо дублировать как внутри квадратных скобок, так и внутри обычных, так как YFM, в отличие от стандартного Markdown, не распознает автоматом URL в тексте:

Github репозиторий YDB: [https://github.com/ydb-platform/ydb/tree/main/ydb/docs](https://github.com/ydb-platform/ydb/tree/main/ydb/docs)

Картинки

Картинки являются частью контента определенной статьи, и размещаются в технической поддиректории _assets в тематической директории, где размещена статья. Вставка картинки в текст статьи осуществляется ссылкой, перед которой указан восклицательный знак !:

![Text](../_assets/file.png)

Указываемый в квадратных скобках текст показывается в браузере пока не загружена сама картинка. Он может повторять имя файла из ссылки без расширения.

Желательные форматы для изображений:

  • Диаграммы: .SVG
  • Скриншоты: .PNG

Так как картинка является частью какой-то статьи, то размещение картинки без статьи невозможно. Если текста статьи пока нет, то необходимо определить тематический каталог размещения и имя файла будущей статьи, в тексте указать только ссылку на картинку (не забыть про то что текст статьи размещается в подкаталоге _includes!), и не включать саму статью в TOC до тех пор, пока он не будет готова к публикации.

Дополнительно при вставке картинки могут быть указаны:

  • Hint для отображения при наведении мышью: ![Text](path/file "Hint"). Пользоваться не рекомендуется, так как многие устройства сегодня не имеют курсора мыши.
  • Размер изображения: ![Text](path/file =XSIZExYSIZE). Рекомендуется пользоваться в варианте указания XSIZE для картинок в формате SVG, чтобы они были растянуты корректно по ширине экрана документации, независимо от того с каким разрешением были сохранены: ![Diagram1](../_assets/diagram1.svg =800x). При указании таким образом только размера по X размер по Y подбирается автоматически с сохранением пропорций.

Обратная совместимость

Развитие документации не должно приводить к тому, что у её пользователей перестанут работать сохраненные ссылки: как закладки в браузерах, так и зафиксированные на множестве неподконтрольных разработчикам документации ресурсах вроде wiki-страниц.

Это означает, что переименовывать статьи, или переносить по директориям в общем случае нельзя.

Если необходимо статью преобразовать в набор статей в пределах новой директории, то для сохранения совместимости данная директория должна получить то же имя, что раньше было у статьи, а внутри должна появиться статья index.md. В результате, по старой ссылке на статью пользователи начнут попадать на страницу "Обзор" новосозданной директории.

Если без переноса никак не обойтись, то можно применить следующий механизм:

  1. По старому месту расположения публикуется статья с контентом "Данная статья больше не существует, новое место размещения <здесь>, обновите ссылку", или вариации на тему этого контента. Главная задача -- чтобы при проходе по старой ссылке пользователь не получил HTTP 404 Not found, а смог понять куда оно переместилось, на что разбилось, или что вообще правда удалено и почему.
  2. В TOC в старом месте расположения указывается ссылка на эту статью с включенным флагом hidden:
    - name: Deprecated article
      href: old_article.md
      hidden: true
    

В результате, данная статья не будет перечислена где-либо в TOC, но будет доступна при проходе по прямой ссылке, если она осталась где-то сохранена.