#article

2024-06-26

Эрзац-Hugo

Не раз мигрировал свой хобби-сайт на разные движки. Было несколько проектов на PHP, превращающихся в разные статические генераторы:

Потом брал специализированные генераторы:

К Hugo приладил вспомогательный скрипт на Bash, причёсывающий сгенерированный результат. Собиралось это всё равно на локальной машине и загружалось на удалённый сервер через Git. Подумал, почему бы не заменить Hugo на свою реализацию полностью на Bash, ведь там всё просто: перебирай себе файлы, преобразуя Makdown в HTML, оборачивая в шаблон.

Первым этапом так было и сделано. Система шаблонов получилось даже удобнее, чем у Hugo, как и управление разделами: теперь это просто контент в папках без каких либо настроек и служебных файлов. Индексные файлы наполнялись ссылками на все остальные файлы из их папок.

Переменные контента (заголовок, дата, описание и другие) хранятся в формате Yaml, как у Hugo. Парсера Yaml как такового нет: файл считывается построчно и всё между первым и вторым --- считается за список переменных вида ключ: значение.

Следующим этапом добавлена генерация страниц тегов. Ещё во время первого прохода собирался список ссылок: к какому тегу какие статьи относятся. Потом всё это записывается в одноимённые файлы /tags/*.html.

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

Как основа ссылок используются пути до файлов без .html, которые перезаписываются через .htaccess, как и на других генераторах. Сначала контент записывался в name.html файлы, в последний момент передалал на структуру name/index.html, как было в Hugo для упрощения просмотра с локальной машины. Внешний результат получился такой же, как у Hugo.

Hugo и Jekyll поставляют свой вебсервер с горячей перезагрузкой контента. Финальный билд делается для загрузки на внешний сервер. В моей версии, понятно, никакого сервера нет - это только генератор. Все ссылки обычно идут от корня /, поэтому для просмотра нужен локальный вебсервер. Можно использовать микровебсервер python3 -m http.server 8000 или другой. Для предпросмотра придётся собрать полный билд.

Скрипт вышел немного запутанный, т.к. Bash знаю плохо и активно пользовался ChatGPT, но совсем без понимания ничего бы реализовать не получилось.

Полные возможности скрипта build.sh:

Есть зависимость от большого стороннего пакета pandoc для обработки Markdown и необязательного пакета tidy для форматирования результата. Парсер pandoc немного отличается от Hugo и пришлось перебрать контент. В частности, pandoc требует отбивку списков пустыми строками. Я часто не отбивал список от параграфа. Ещё он добавляет теги p внутрь li, что пришлось визуально скорректировать через CSS.

Время сборки зависит от контента. На сотне записей и 50МБ статических файлов работает около пяти секунд. Половину из этого занимает pandoc. Дополнительно исследовал другие парсеры Markdown. Скорость сравнивается относительно pandoc.

Итого можно оставить pandoc для полного функционала или markdown с расстановкой хешей через JS.

UP: позже дописал скрипт watch.sh, который предоставляет как бы автоматическую систему сборки с автозапуском сервера разработки. Всё ещё без hot reload, но это может быть реализовано плагинами браузера (не проверял).