Hatred's Log Place

DON'T PANIC!

Jan 3, 2020 - 4 minute read - blog

Hugo: редактирование страницы из браузера

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

Мой блог хостится на 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/"
  ...

Что в итоге?

  1. При открытии сайта в браузере у нас есть ссылка на редактирование страницы через интерфейс GitLab (или другой используемой системы):
    • переходим
    • редактируем
    • сохраняем
    • ждём
    • PROFIT
  2. При открытии локального сайта по ссылке localhost:1313 у нас есть ссылка со схемой markdown: которая позволяет запустить системный редактор, отредактировать страницу и сразу увидеть результат. После чего мы можем отредактировать следующую страницу и отправить это на GitLab в один push-запрос.

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

Сниппет без изменений подошёл и для прочих страниц:

Tags: site blog

Markdown Converters Внезапный Homebrew

comments powered by Disqus