Блог писал статьи, но жил по-простому: правишь текст — он сразу меняется у всех, комментариев нет, а о новом посте я узнавал, только если сам открывал сайт. За последние дни я закрыл эти дыры. Вот что изменилось и почему именно так.
Версии: правлю, не ломая то, что видят читатели
Главный страх автора — опубликовал, потом начал править и мимоходом сломал текст, который уже читают. Поэтому теперь редактирование опубликованного поста не затирает его сразу: изменения уходят в ожидающую версию, а читатели продолжают видеть прежнюю.
Работает это так: «Save» на опубликованном посте — изменения ждут; «Publish changes» — применяю, и прежняя версия уходит в историю; «Discard» — отменяю. Черновики и новые посты, как и раньше, пишутся сразу.
История и дифф
Раз версии копятся, к ним нужен доступ. В редакторе появилась кнопка History: список прошлых версий и цветной дифф против текущей — видно, что именно менялось и в какой строке. При публикации прежняя версия автоматически уходит в архив, так что «откатиться» не страшно.
Комментарии: почему не встроенный виджет
Комментарии я решил не писать с нуля, а взять зрелый опенсорс — Remark42: один контейнер, хранение у меня, модерация и антиспам из коробки.
Но встроенный виджет меня победил. Он рендерится в iframe, а значит внешний CSS его не достаёт — темизировать можно только через внутренние CSS-переменные. Беда в том, что переменные у Remark42 не семантические: --color5, --color7, --color22 используются то как фон, то как цвет текста. Я подкрутил фон поля ввода — и получил невидимый текст; подтянул панель — всплыло светлое пятно. Классическая ловушка: чужие переменные без смысла.
Свой интерфейс поверх API
Решение пришло быстро: раз виджет не приручить — рисуем свой. Список и форму комментариев я сделал на своих шаблонах, в дизайн-системе сайта, а данные и хранение оставил в Remark42 через его API.
Технически это оказалось интереснее в хорошем смысле. Создание комментария — защищённая операция, и сервер сам выпускает токен посетителя (подписывая его общим секретом Remark42), поэтому форма публикует комментарий от имени гостя без сторонних embed-ов. Внешне теперь всё — мой код, поэтому стиль совпадает идеально.
Модерация внутри bagilov_tech
Отдельным сервисом в приложении сделал модерацию: список комментариев и действия — удалить, закрепить, заблокировать автора. Он ходит в Remark42 как админ, и снова без внешних логинов: нужный JWT я выпускаю сам.
Здесь пришлось разобраться в деталях: токен принимается только с правильным aud и полем auth_provider, а операции по id требуют URL статьи — иначе Remark42 отвечает «no bucket». Мелочи, но без них ничего не работало.
Уведомления в ntfy
Наконец, я хотел знать о событиях, не открывая сайт. Завёл в ntfy отдельный топик blog (алерты Grafana остались в alerts). Теперь туда приходят: новая публикация со ссылкой, новый комментарий со ссылкой на статью, и результат модерации. Пуш на телефон — в приложении ntfy.
Что понял
Кастомизация чужого компонента — это паритет: пока подстраиваешься под его переменные, он подстраивает тебя под свои допущения. Иногда дешевле не бороться, а взять его как движок и нарисовать интерфейс самому. Блог стал ровно таким, каким я его вижу, — и молчать он больше не будет.
Загрузка…