Markdown база знаний (или блог, или документация проекта)

в 19:24, , рубрики: html, javascript, markdown, node.js, nodejs, хранение данных

Заметил за собой, что постоянно записываю всякие мелочи, полезную информацию, просто что-то из буфера обмена прямо в текстовом редакторе. Всегда где-то на фоне висит открытый Sublime Text с кучей вкладок.
И ещё я заметил, что мне удобнее всего структурировать информацию в одном файле используя синтаксис Markdown — приятнее именно исходный текст, а не результат, отображаемый на том же гитхабе.
Со временем я заметил, что таких сохраненных файлов накопилось немало, да и незакрытые вкладки убавляться не собираются. А ведь одно неосторожное движение и вся не сохранённая накопленная информация канет в небытие, да и с других устройств не посмотришь, и раскидывать по папочкам тоже не очень удобно.
Всё это привело меня к мысли написать что-то вроде своего движка для хранения всей информации в одном месте и в удобном виде. Да-да, есть куча всяких Evernote, каких-нибудь заметок, встроенных в MacOS/iOS и так далее, которые и синхронизируются, и фичи полезные имеют — но, как говорится, хочешь сделать что-то хорошо (для себя), сделай это сам. Да и, как почти любой программист, в любой непонятной ситуации я беру и пишу всё сам. Так вышло и в этот раз.

Markdown база знаний (или блог, или документация проекта) - 1

Зачем?

Подобные проекты уже существуют, да и вышеупомянутые сервисы-монстры тоже довольно удобны, но некоторые свои фичи в моём проекте дают некоторые преимущества.

В первую очередь его удобнее всего использовать как документацию для проекта (собственно, вдохновление пришло от сайта с документацией по Kotlin, откуда я и позаимствовал большую часть стилей для сгенерированного контента).

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

Что умеет?

  • Генерация HTML на лету — результат не сохраняется. Уже готовые статьи можно целыми папками копировать в нужную директорию проекта. Все добавляемые и удаляемые файлы индексируются автоматически.
  • Навигация тоже генерируется, а не хардкодится.
  • Поиск по содержимому.
  • Управление доступами — работает примерно как «группы» у организаций на гитхабе: каждой группе (я назвал их role) принадлежит список юзеров и список путей до папок/файлов, которые могут смотреть юзеры этой группы.
  • При поиске, в навигации и т.д. юзер не увидит те страницы, к которым не имеет доступа.
  • Статьи также можно добавлять в визуальном редакторе (в нём есть подсветка синтаксиса, кнопочки как на гитхабе, предпросмотр и т.д.)
  • Всё легко конфигурируется через страницу с настройками, которая тоже сгенерирована (и добавлять новые пункты можно без труда). Итого — можно за пару команд установить локально проект, скинуть в папочку готовые Markdown-файлы, быстро настроить доступы и пользоваться.
  • Куча других мелких фишек, вроде ссылок-якорей на все заголовки, кнопок для копирования над сниппетами с кодом и т.д. и т.п.

Как работает?

На чём?

Я использовал NodeJS и express, так как для меня данный стек показался самым минимально ресурсо-временезатратным для реализации этой конкретной задачи.

Права доступа

Логика довольно проста — passport решает все проблемы с авторизацией. Права для пользователей и статей хранятся в MongoDB, а пути до статей соответствуют путям до файлов на диске.
Сами «группы» нигде не хранятся, управление происходит «снизу»: у каждого юзера и пути (до статьи или категории — т.е. до файла и папки) есть свой список «ролей». Если у юзера есть хотя бы одна «роль» из списка пути, по которому он переходит, то считается, что у него есть доступ. Для просмотра любого пути юзер должен иметь доступ к самому пути и ко всем родительским: например, чтобы увидеть страницу /pages/Documentation/Habr, нужно иметь доступ к /pages, /pages/Documentation и к /pages/Documentation/Habr.

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

Статьи

Для конвертации используется библиотека для Ruby, которая называется kramdown — все её фичи тоже поддерживаются.
После генерации HTML разметка встраивается в подготовленный шаблон, куда ещё встраивается сгенерированная навигация.

Генерация навигации работает довольно просто — рекурсивно получается полный список всех файлов и папок, затем они фильтруются по правам пользователя, а уже результативная структура «насаживается» на шаблон.

Поиск работает точно также.

Для оформления я использовал materialize, стили с сайта документации Kotlin для самих статей, по мелочи брал идеи с редактора на гитхабе и т.д.


Исходный код доступен здесь: https://github.com/petersamokhin/nodejs-markdown-site

Не являюсь NodeJS — или бэкенд-разработчиком, но люблю отвлечься на что-то интересное. Статью написал потому что подумал, что штука выглядит вполне полезной.
Да, есть аналоги с той же идеей (если честно, узнал уже после разработки) — но многих вышеописанных (и не описанных здесь) фич у них нет, а реализация выглядит сложнее: тот же сайт документации Kotlin хардкодит навигацию, из дополнительных фич умеет исполнять код и, вроде бы, всё, — хотя сам проект немаленький.


P.S. правил Хабра я, вроде бы, не нарушил и кроме ссылки на гитхаб и общего описания статья не содержит. Если вдруг люди проявят интерес, я могу написать серию статеек с подробным описанием всего процесса разработки или конкретных моментов — ибо одной статьёй здесь вряд ли получится отделаться.

Автор: Пётр Самохин

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js