
Всем привет! Мы продолжаем разбирать наши решения. Сегодня расскажем о том, как, используя генератор Material for MkDocs, можно создать несложный, но удобный статический сайт с документацией (и не только!).
А ещё как встроить его в CI/CD для автосборки и автопубликации (мы используем Gitlab CI, о чём подробно рассказывалось в предыдущем туториале), а также как использовать плагины к генератору чтобы, к примеру, создавался не только сайт, но и его pdf-представление.
Добро пожаловать под кат!
Оглавление
-
Что такое генератор статического сайта? И почему был выбран именно MkDocs?
-
Как и на каком языке писать материалы для генератора MkDocs?
Перед началом
В этот раз мы публикуем не просто куски кода — мы выложили в открытый доступ весь «боевой» репозиторий с текущей документацией, а также скриптами сборки этого сайта.
Самые нетерпеливые могут сразу посмотреть репозиторий на сайте gitlab.com.
Что такое генератор статического сайта? И почему был выбран именно MkDocs?
Генератор статического сайта это программа, собирающая полноценный сайт из одного или нескольких шаблонов, а также материалов для сайта.
Создание или редактирование статического сайта выполняется предельно просто:
-
Владелец создаёт новый файл или редактирует существующий в человекочитаемом формате (например, в markdown).
-
Далее запускается генератор статического сайта — и результатом работы он выдаёт сайт в виде набора html-страниц с уже применённой темой, форматированием, построенным оглавлением и пр.
-
Полученный сайт владелец уже может использовать локально. Ну или выложить на каком-либо хостинге — чтобы к нему могли получить доступ другие люди.
И важно отметить: для статических сайтов не требуется поддержка каких-либо серверных языков и/или баз данных — всё уже свёрстано и готово к использованию.
Минусом же статических сайтов является то, что все пользователи будут видеть один и тот же контент (то есть сделать авторизацию, разделение на роли и прочее не получится).
Немного личных впечатлений
19 мая 2015 года Rich Lander сделал первый коммит в репозиторий с комментарием «Experimenting with docs». Похоже, что именно с этого коммита и началась история docs.microsoft.com — проекта, содержащего на текущий момент документацию по огромному количеству языков, технологий и продуктов Microsoft.
Впервые попав на этот сайт, я был поражён:
-
на сайте имелась «гибкая» вёрстка (было удобно смотреть сайт и с компьютеров, и с мобильных устройств),
-
присутствовала удобная навигация с фильтром: находясь в документации по .NET, можно было ввести название класса или метода и сразу перейти к нему.
В дальнейшем на сайте появился автоперевод статей на русский язык (а также возможность переключения и чтения статьи на языке оригинала).
Но самое главное, что меня зацепило — кто угодно (а не только сотрудник Microsoft) мог предложить правки, дополнения или перевод материалов. Ведь все материалы лежали в публичном репозитории github!
И эта идея хранения информации в стиле «предложить новое может каждый» так плотно засела у меня в голове, что, обретя возможность сделать документацию для одного из разрабатываемых приложений, я решил попробовать сделать маленький, но аналог.
На сегодняшний день список самых популярных систем, способных сгенерировать статические сайты, достаточно небольшой:
-
Jekyll. Написан на Ruby, его использует Github для Github Pages (вероятно потому, что один из создателей Jekyll — сооснователь github?).
-
Hugo. Написан на Go, позиционирует себя как самый быстрый генератор статических сайтов.
-
Sphinx. Написан на Python. Именно с его помощью сгенерирована документация к языку Python.
-
MkDocs. Также написан на Python.
MkDocs был выбран как самый популярный генератор на Github (на момент написания статьи у репозитория MkDocs было более 12 тыс. «звёздочек»). А больше всего приглянулся его форк с красивой (по моему мнению) встроенной темой, называемый Material for MkDocs. А всё потому, что сгенерированный с его помощью сайт из коробки предоставлял и гибкую вёрстку, и человекочитаемые url-ы, и встроенный быстрый поиск по всем статьям (который не требует какой-либо серверной реализации).
Создание и генерация тестового сайта
Для того, кто не очень знаком с языком Python, но немного представляет что такое контейнеризация, проще всего воспользоваться MkDocs с использованием их docker-образа.
При подготовке этого материала использовалась ОС Linux (дистрибутив Debian 10).
Перед созданием первого сайта на компьютере выполним в терминале (bash) команду docker pull squidfunk/mkdocs-material для загрузки docker-образа mkdocs.
На заметку: команды docker pull и docker run могут требовать прав суперпользователя. Соответственно, если для выполнения команды не хватает прав, перейдите в режим суперпользователя командой su или воспользуйтесь командой sudo.
Как создать новую папку с материалами для сайта
-
Выберите папку, в которой будут храниться материалы для генерации сайта (например,
/home/user/test/). -
Откройте в указанной папке терминал (или перейдите в существующем терминале в нужную папку (например, командой
cd /home/user/test/). -
Выполните в открытом терминале команду
docker run --rm -it -v ${PWD}:/docs squidfunk/mkdocs-material new .
В результате в нашей папке появятся два новых файла:
. ├─ docs/ │ └─ index.md └─ mkdocs.yml
Файл mkdocs.yml — это файл конфигурации, используемый MkDocs. Файлы, находящиеся в папке docs (в частности, index.md) — это исходные материалы, из которых в дальнейшем будет сгенерирован наш сайт.
Как сгенерировать сайт по существующим материалам
Выполните в терминале, открытом в папке с материалами (папке с файлом mkdocs.yml) команду
docker run --rm -it -v ${PWD}:/docs squidfunk/mkdocs-material build
В результате в папке с материалами появилась подпапка site, в которую генератор записал наш только что созданный сайт. Выглядит он следующим образом:
Как пересоздавать сайт «на лету» при внесении изменений в файлы
MkDocs умеет также создавать превью сайта «на лету», отслеживая изменения в исходных материалах в реальном времени и перестраивая только их. Для включения такого режима выполните в терминале, открытом в папке с материалами (папке с файлом mkdocs.yml) команду
docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material
Пока команда выполняется (прервать её можно, нажав комбинацию клавиш Ctrl+C), на вашем компьютере на порту 8000 будет запущен веб-сервер, который вы можете использовать для просмотра результатов ваших правок на сайте. Просто откройте браузер, введите в строке адреса http://localhost:8000/ — и смотрите как выглядит сгенерированный сайт (правда, для обновления текущий страницы придётся нажимать F5).
Как и на каком языке писать материалы для генератора MkDocs?
Генератор сайтов MkDocs в качестве исходных материалов поддерживает файлы как формата markdown (.md) так и формата html.
Стоп-стоп, скажете вы. Html? Зачем нам генерировать сайт из «материалов» на языке html, если результат — всё равно html?!
Дело в том, MkDocs не только преобразовывает markdown в html, но и корректно применяет к этим страницам темы, а также даёт простор для работы своим многочисленным плагинам, которые: осуществляют подсветку кода, индексируют содержимое для быстрого поиска, могут сгенерировать PDF-содержимое одной страницы или всего сайта и т.д.
Таким образом давайте условимся: исходные материалы это то, что содержит информацию и минимум применения сложных разметки, стилей и прочего, а сгенерированный сайт это результат работы генератора, содержащий те же тексты, что и в исходных материалах, но уже с применёнными темами и иным добавленным генератором содержимым.
Что же писать в исходных материалах?
Да в принципе всё, что захотите. MkDocs полностью поддерживает синтаксис markdown. Для примера картинка с markdown-текстом слева и сгенерированным из него html справа:
Более подробно о формате markdown и о том, как оформлять такие документы, написано в шпаргалке по markdown.
И, — что для меня оказалось очень важно — MkDocs совершенно нормально относится к html-тэгам как внутри html, так и внутри markdown-файлов.
Нам это пригодилось для вставки в начало некоторых страниц справки html-плеера с видеоуроком по той же теме, что описана в материале.
Разбираем структуру файла mkdocs.yml
Давайте подробнее изучим содержимое созданного на предыдущем шаге файла mkdocs.yml
site_name: My Docs
Негусто.
К счастью, все сайты с документацией по MkDocs собраны с помощью генератора MkDocs и можно посмотреть содержимое mkdocs.yml, к примеру, сайта https://www.mkdocs.org/.
Приведём содержимое этого файла с дополнительными комментариями, на что влияют указанные в файле параметры:
# [Обязательное] Название сайта site_name: MkDocs # Базовый адрес сайта site_url: https://www.mkdocs.org/ # Описание сайта. Добавляется в meta в html-заголовке каждой страницы. site_description: Project documentation with Markdown. # Автор (или авторы) сайта. Добавляется в html-заголовок каждой страницы. site_author: MkDocs Team # Ссылка на репозиторий, в котором хранятся исходные материалы. repo_url: https://github.com/mkdocs/mkdocs/ # Относительный путь, который в сочетании со ссылкой на репозиторий (repo_url) # и относительным адресом страницы даст адрес, по которому можно вызвать # редактор страницы. Для repo_url-ов известных площадок (например, # GitHub или GitLab можно оставить пустым - он подставится автоматически) edit_uri: "" # Информация о теме, которая будет применена для сгенерированного сайта. # И её параметрах theme: name: mkdocs locale: en analytics: {gtag: 'G-274394082'} highlightjs: true hljs_languages: - yaml - django # Структура навигации генерируемого сайта. nav: - Home: index.md - Getting Started: getting-started.md - User Guide: - Overview: user-guide/index.md - Installation: user-guide/installation.md - Writing Your Docs: user-guide/writing-your-docs.md - Choosing Your Theme: user-guide/choosing-your-theme.md - Customizing Your Theme: user-guide/customizing-your-theme.md - Localizing Your Theme: user-guide/localizing-your-theme.md - Configuration: user-guide/configuration.md - Deploying Your Docs: user-guide/deploying-your-docs.md - Developer Guide: - Overview: dev-guide/index.md - Themes: dev-guide/themes.md - Translations: dev-guide/translations.md - Plugins: dev-guide/plugins.md - About: - Release Notes: about/release-notes.md - Contributing: about/contributing.md - License: about/license.md extra_css: - css/extra.css # Список подключённых расширений для препроцессора языка Markdown markdown_extensions: - toc: permalink: - admonition - attr_list - def_list - mdx_gh_links: user: mkdocs repo: mkdocs copyright: Copyright © 2014 <a href="https://twitter.com/_tomchristie">Tom Christie</a>. # Список использованных плагинов MkDocs plugins: - search - redirects: redirect_maps: user-guide/plugins.md: dev-guide/plugins.md user-guide/custom-themes.md: dev-guide/themes.md user-guide/styling-your-docs.md: user-guide/choosing-your-theme.md
На что хочется обратить внимание в структуре навигации из примера выше:
-
Путь страницы в url будет сгенерирован из
site_urlи относительного пути страницы в репозитории. Например, страницаUser Guide -> Overviewбудет доступна по urlhttps://www.mkdocs.org/user-guide/index.html(потому, что файл, из которого сгенерировали страницу, имел относительный путьuser-guide/index.md). -
Один файл можно указать в навигации и более одного раза.
-
Если файл отсутствует в разделе
nav— соответствующая страница всё равно будет сгенерирована, но не будет показана в навигации сайта. При этом перейти на неё, зная её url (см. первый пункт списка), вполне себе можно. -
Плагин redirects (подробнее об использовании плагинов расскажу чуть ниже) позволяет настроить переадресацию страниц со старого расположения на новое.
Более подробно о структуре файла mkdocs.yml а также на то, как он влияет на используемую тему, расскажет подробная справка на сайтах mkdocs.org, Material for mkdocs а также примеры файлов mkdocs.yml в других репозиториях.
Настраиваем Gitlab CI и Gitlab Runner для генерации статического сайта
Следующий этап — это добавление сайта в систему контроля версии (СКВ) и написание скрипта, который сам собирал бы нам сайт как только мы сохраним новую его версию.
Воспользуемся git-ом как СКВ и Gitlab CI для обработки действий.
Внимание. У вас может возникнуть вопрос: а зачем мы, собственно, настраиваем Gitlab CI, если выше была показана команда serve, которая на лету создаёт сайт и поддерживает его в актуальном состоянии при изменениях в файлах?
Ответ включает как минимум следующие пункты:
-
Команда
serveне обеспечивает сохранение истории изменений, а СКВ для этого и предназначена. -
Команда
serveне предназначена для работы в production-окружении. В частности, serve может «сломаться» если при очередной сборке произошла ошибка (например, структура mkdocs.yml стала некорректной).
Поскольку многие читатели знакомы с git, я уберу под спойлер инструкцию по созданию репозитория и его сохранению (пушу) в Gitlab.
Инструкция по созданию репозитория и пушу его в Gitlab
Нам потребуется установленный консольный или графический клиент git-а. По устоявшейся уже в сообществе традиции процесс в этой статье будет описан консольными командами.
Итак, для создания нового репозитория откройте терминал в папке с материалами, после чего:
-
Создадим файл .gitignore и внесём в него 1 строку (команду игнорировать папку site); для этого в терминале введём команду
echo '[Ss]ite/' > .gitignore -
Создадим репозиторий командой
git init -
Создадим первый коммит, состоящий из всех созданных нами файлов
git add -A git commit -m 'Сайт в состоянии hello, world'
Если при попытке выполнения команды git gommit команда выдаст ошибку из-за на отсутствия имени и/или электронной почты, то введите следующие две команды
git config user.name "<имя, которое будет отображаться в коммитах в этом репозитории>" git config user.email "<электронная почта, которая будет отображаться в коммитах в этом репозитории>"
После чего повторите команду git commit.
Теперь осталось создать в gitlab новый проект, перейти на страницу созданного проекта, найти и скопировать на странице ссылку на репозиторий (она выделена в отдельную рамочку и снабжена кнопкой «скопировать»).
Далее воспользуемся этой ссылкой для сохранения созданного репозитория в созданный проект gitlab:
git remote add origin <ссылка на проект gitlab> git push -u origin master
Теперь, когда репозиторий создан и связан с Gitlab, создадим в папке с исходными материалами файл .gitlab-ci.yml. О структуре этого файла мы кратко рассказывали в предыдущей публикации. Посему не будем подробно останавливаться на структуре, лишь приведём код файла:
stages: - build build_docs_job: stage: build # tags: docker # раскомментируйте эту строку если вам # потребуются метки для определения конкретного Runner-а # (см. ниже) only: - /^master$/ - merge_requests image: name: squidfunk/mkdocs-material entrypoint: [""] script: - 'mkdocs build --site-dir site' artifacts: name: "site_$($CI_PIPELINE_IID)" paths: - site
Этим файлом мы указали Gitlab CI собирать сайт каждый раз, когда появляются новые коммиты в ветке master или в процессе создания или обновления merge request-ов.
Конечно, для того, чтобы это заработало, потребуется установить Gitlab Runner на машину, которая и будет собирать сайт по написанной в файле .gitlab-ci.yml «инструкции».
На заметку: подробную и актуальную инструкцию по установке Gitlab Gunner на ту сборку ОС Linux, что установлена у вас, можно посмотреть на сайте документации Gitlab.
Ниже для примера мы приведём пошаговую инструкцию как это сделать для ОС Debian Linux:
-
Посмотрите токен для регистрации Runner-а в вашем Gitlab. В зависимости от того, где будет доступен ваш Runner:
-
только в одном проекте — смотрите токен в меню проекта Settings > CI/CD в разделе Runners,
-
в группе проектов — смотрите токен в меню группы Settings > CI/CD в разделе Runners,
-
для всех проектов Gitlab-а — смотрите токен в секции администрирования, меню Overview > Runners.
-
-
Найдите актуальную для вашей архитектуры версию Gitlab Runner на сайте https://gitlab-runner-downloads.s3.amazonaws.com/latest/index.html.
-
Скачайте нужный deb-пакет с помощью браузера или команды в терминале
curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_${arch}.deb", где${arch}следует заменить на выбранную вами архитектуру. -
Выполните в терминале команду для установки скачанного пакета Gitlab Runner
sudo dpkg -i gitlab-runner_<arch>.debгде<arch>опять же, следует заменить на выбранную вами архитектуру. -
Зарегистрируйте раннер командой
sudo gitlab-runner registerДалее потребуется ввести ответы на вопросы мастера регистрации Runner-а:-
coordinator URL — http или https адрес вашего сервера gitlab;
-
gitlab-ci token — введите токен, полученный на предыдущем шаге;
-
gitlab-ci description — описание Runner-а, которое будет показываться в интерфейсе Gitlab-а;
-
gitlab-ci tags — через запятую введите тэги для Runner-а. Если вы не знакомы с этим механизмом, оставьте поле пустым. Отредактировать его можно позднее через интерфейс самого gitlab-а. Тэги можно использовать для того, чтобы определённые задачи выполнялись на определённых Runner-ах (например, чтобы настроить сборку ПО на Runner-е, развёрнутом на компьютере ОС Windows, а подготовку документации на Runner-е с ОС Linux);
-
enter the executor — ответьте
docker. На этом шаге указывается оболочка, в которой будут выполняться команды.
-
На заметку: если у вас несколько runner-ов с разными исполнителями (например, shell для сборки ПО, а docker для сбора документации), настройте тэги для этого раннера. Для этого добавьте в тэги раннера, например, слово docker — и уберите первый символ решётки (#) из файла .gitlab-ci.yml. Ну или аналогичным образом настройте тэг с другим именем.
Проверим работу того, что настроили — сделаем коммит с созданным кодом. Можно прямо в ветку master, если, конечно, вы работаете в тестовом репозитории. В ином случае рекомендуем создать отдельную ветку с этими изменениями, затем создать на эту ветку merge request.
Делаем свой docker-образ и добавляем в него плагин для генерации PDF-файла («печать всего сайта»)
Что ж, в целом проект уже работает. Однако для того, чтобы им воспользоваться, требуется либо соединение с интернетом, либо передать клиенту много html-страничек. Но что если требуется, к примеру, распечатать все материалы? Давайте настроим экспорт всего сгенерированного сайта в формат PDF и добавим его в артефакты Gitlab CI.
Стандартный функционал MkDocs сделать печать в PDF не позволят — но не беда, для этого и многих других функций сам генератор поддерживает плагины. И нас будет интересовать плагин mkdocs-with-pdf.
Чтобы добавить его в docker-образ генератора, потребуется модифицировать этот образ. И сделать это можно буквально в пару строк:
-
Создайте в папке с файлом mkdocs.yml новый файл с именем dockerfile
-
Добавьте в него следующие строки:
FROM squidfunk/mkdocs-materialRUN pip install mkdocs-with-pdf -
Откройте страницу Container Registry в вашем проекте в Gitlab (<адрес вашего проекта в gitlab>/container_registry, на картинке стрелочки 1 и 2), подсмотрите на ней имя образа, которое следует использовать при сборке (стрелочка 3).
Страница Container Registry в Gitlab -
Откройте терминал в папке с файлом Dockerfile и выполните в нём команду сборки модифицированного образа:
sudo docker build -t <имя образа, которое следует использовать> .С вероятностью 100% сборка образа закончится ошибкой так как образ
squidfunk/mkdocs-materialоснован на Alpine Linux, где многие компоненты (типа компилятора gcc) по умолчанию отсутствуют. Чтобы образ собрался корректно. нам понадобится перед установкой пакета загрузить все необходимые не связанные с python-ом зависимости для него.После дописывания зависимостей (которые были у плагина на момент написания статьи) файл Dockerfile будет выглядеть следующим образом:
FROM squidfunk/mkdocs-materialRUN apk add build-base ttf-ubuntu-font-family libffi-dev zlib-dev
libwebp-dev jpeg-dev harfbuzz-dev fribidi-dev freetype-dev
cairo-dev musl-dev pango-dev gdk-pixbuf-dev
&& pip install mkdocs-with-pdf -
Когда сборка завершилась успехом, авторизуемся на сервере gitlab через докер, после чего загружаем полученный образ на сервер:
docker login <имя образа для сервера gitlab, указанное на странице Container Registry>docker push <имя образа для сервера gitlab, указанное на странице Container Registry>И осталось только отредактировать mkdocs.yml чтобы включить в нём сборку сайта в PDF-файл. Для этого добавим раздел plugins, в котором перечислим все включаемые плагины (в данном случае только один —
with-pdf), а также их параметры.
site_name: My Docs # На заметку: без явного указания темы пересобранный с плагином образ material-mkdocs сайт собрать не может theme: name: material plugins: - with-pdf: cover: true cover_title: My Docs cover_subtitle: версия для PDF copyright: (C) 2021 Rostelecom PJSC toc_title: Оглавление toc_level: 3 output_path: ./help.pdf
Пара слов об использованных параметрах:
-
cover_title — заголовок, который будет указан на сгенерированной странице PDF. Может отличаться от названия сайта.
-
cover_subtitle — подзаголовок, который будет указан на сгенерированной странице PDF.
-
copyright — копирайт.
-
toc_title — название оглавление (по умолчанию contents).
-
toc_level — оглавление по умолчанию строится сначала по структуре навигации, а затем по заголовкам в документе. Параметр toc_level указывает максимальный уровень заголовка, который включается в оглавление. Например, значение 3 говорит о том, что все заголовки от первого до третьего уровня (h1 — h3).
-
output_path — путь имя сгенерированного pdf-файла.
Полный их список доступен на странице плагина.
Запускаем в терминале сборку сайта (уже нашим образом)
docker run --rm -it -v ${PWD}:/docs <имя образа для сервера gitlab, указанное на странице Container Registry> build
И убеждаемся, что в корневой папке появился файл help.pdf со всем содержимым сайта, а также кликабельным оглавлением
Послесловие
На текущий момент мы продолжаем улучшать генерацию сайта со справочной информацией, а также стараемся наполнять и поддерживать его.
В рамках этой статьи были рассказаны лишь основы, однако мы уже двигаемся дальше:
-
Добавлен плагин
monorepoдля сборки сайта из нескольких отдельно живущих папок с материалами. Мы скомбинировали плагинmonorepoс плагиномwith-pdfчтобы можно было собирать и отдельные части сайта в PDF (будут только некоторые тонкости при указании папки с переопределениями темы при генерации части сайта). -
Включены плагины
search(поиск по сайту) иgit-revision-date(чтобы отображать дату последнего изменения страницы). -
Тема сайта дорабатывается под корпоративные стандарты.
-
Также дорабатывается возможность автогенерации PDF-файла для справки прямо в процессе сборки нашего ПО (так как, в частности, материалы из раздела «Настольное приложение» поставляются вместе с ПО «Настольное приложение Видеонаблюдение»).
Если у вас будут вопросы — пишите в комментариях, мы с радостью ответим. Есть предложения по улучшению? — разделы issues и merge requests мы тоже просматриваем достаточно оперативно.
И спасибо за прочтение!
ссылка на оригинал статьи https://habr.com/ru/articles/570098/
Добавить комментарий