Ну точнее не совсем. Статичный сайт на то и статичный, что вся генерация производится где-то там. Но иметь возможность получить ссылку на файл для редактирования конкретной страницы - достаточно удобная вещь.
Мой блог хостится на GitLab Pages, в отличии от GitHub Pages, он предоставляет больше возможностей (по крайней мере пока) по использованию различных генераторов сайтов. Так, в репозитории у меня хранится исходный код сайта, а генерация производится через CI и запуск Hugo, после чего артефакты деплоятся (ограничение - 1GB). В GitHub Pages автоматически генерировать сайт из исходников возможно только при использовании Jekyll.
Сами системы, что GitLab, что GitHub позволяют редактировать документ из браузера. На этом у меня и основывалась первоначальная идея, как править документы онлайн, если есть доступ только к браузеру. Собственно уже давно на этом сайте можно увидеть значок карандаша рядом со статьями блога.
Но мне хотелось большего.
Как известно, у Hugo есть режим сервера, когда он рендерит документы (по умолчанию - в память) и запускает сервер, доступный по адресу localhost:1313. Естественно, если мы перейдём по ссылке и запустим редактирование онлайн, мы документ отредактируем, но только непосредственно на сайте. А если мы хотим правок только локально? А потом только закоммитить и опубликовать?
Чуточку подумав, решил, что самый простой способ достичь желаемого - это использовать следующие возможности:
- переменную
hugo.Environment
, которая, по умолчанию (для своих вариантов использовать параметр-e
/--environment
) задана в “development” при запуске из режима сервера и “production” при запуске в режиме генерации сайта. - функцию
getenv
, что бы получить переменную окружения, через которую мы передадим ссылку на корень блога. - использовать параметр сервера
--navigateToChanged
что бы браузер с отрктым сайтом Hugo автоматически редиректился на изменённую страницу - это оказалось очень удобно, когда редактируешь документы, обходя файловую систему.
Собираем всё вместе и получаем следующий сниппет, который стоит поместить в один кусочков шаблона сайта (у меня это “ layouts/partials/post_header.html”):
{{ if eq hugo.Environment "development" }}
{{ if getenv "HUGO_SITE_ROOT" }} <a href="markdown:{{ getenv "HUGO_SITE_ROOT" }}/content/{{ .File.Path }}"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a> {{ end }}
{{ else }}
{{ if .Site.Params.editPrefix }} <a href="{{ .Site.Params.editPrefix }}/content/{{ .File.Path }}"><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a> {{ end }}
{{ end }}
Запуск сервера производится скриптом hugo-server.sh
следующего содержания:
#!/usr/bin/env bash
#HUGO=hugo
HUGO=/usr/bin/hugo
SITE_ROOT=$(pwd)
env HUGO_RSSLIMIT="-1" HUGO_SITE_ROOT="$SITE_ROOT" \
$HUGO server -D -F -E --watch --verbose --disableFastRender --navigateToChanged
Корень исходника сайта передаётся через переменную окружения HUGO_SITE_ROOT
. Дальше строится полный путь уже в самом шаблоне.
Обратите внимание на используемую схему для файла: markdown:
, а не file:
. Дело в том, что как минимум, Firefox игнорирует схему file:
и нужны дополнительные приседания, что бы заставить её работать. Для все прочие схемы, он пытается запустить через определённый пользователем хендлер. Собственно при первом переходе по такой ссылке вас и спросят, а что с этим делать-то? И указать обработчик этой схемы.
А что бы получить желаемый результат, нужно создать скрипт, например, markdown-handler
в любом удобном месте и сделать его исполняемым:
touch ~/bin/markdown-handler
chmod +x ~/bin/markdown-handler
Содержимое этого файла может быть следующим:
#!/usr/bin/env bash
editor=typora
#editor=xdg-open
schema="${1:0:9}"
# skip unknown schemas
[ "$schema" != "markdown:" ] && exit 0
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
$editor "$(urldecode ${1:9})"
xdg-open
откроет системный хендлер, который закреплён за данным типом файла. Если он не устраивает, имеет смысл изменять системные настройки. В крайнем случае, переопределить обработчик (программу для открытия) прямо в скрипте.
Дополнительно можно проделать действия по ссылке:
что бы научить открывать схему markdown:
стандартный xdg-open
, тогда без подобные ссылки начнут понимать и браузеры, основанные на Chromium, правда проверял я только в Vivaldi. Ну и дефолтный хендлер “System handler” в Firefox тоже начнёт работать для этих ссылок.
Если в паре слов, то создать файл .local/share/applications/markdown-protocol-handler.desktop с содержимым:
[Desktop Entry]
Type=Application
Name=Markdown Scheme Handler
Exec=markdown-handler %u
StartupNotify=false
MimeType=x-scheme-handler/markdown;
И выполнить команду:
xdg-mime default markdown-protocol-handler.desktop x-scheme-handler/markdown
Сам markdown-handler
мы выше уже создали.
Совсем забыл: в сниппете выше упоминается параметр .Site.Params.editPrefix
. Это пользовательский параметр, который задаётся в config.toml:
[params]
...
editPrefix = "https://gitlab.com/USER/USER.gitlab.io/edit/master/"
...
Что в итоге?
- При открытии сайта в браузере у нас есть ссылка на редактирование страницы через интерфейс GitLab (или другой используемой системы):
- переходим
- редактируем
- сохраняем
- ждём
- …
- PROFIT
- При открытии локального сайта по ссылке
localhost:1313 у нас есть ссылка со схемой
markdown:
которая позволяет запустить системный редактор, отредактировать страницу и сразу увидеть результат. После чего мы можем отредактировать следующую страницу и отправить это на GitLab в один push-запрос.
На данный момент, ссылка у меня создаётся только для постов блога. Придёт время и дойдут руки, сделаю аналогичное и для прочих страниц.
Сниппет без изменений подошёл и для прочих страниц: