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

Отдельно расскажу про комментарии. Теперь они встроены в блог, являются его частью, а не лежат на серверах Disqus. Для этого я написал импорт из XML. Ясное дело, на Кложе, исходники на Гитхабе.

Если вкратце, код пробегает по XML, строит мапы и индексы по ID. Для каждого комментария он создает файл вроде _comments/2016-08-08-08-27-14.md с содержимым:

---
id: 2826354744
is_spam: false
is_deleted: false
post: /interview/
date: 2016-08-08T08:27:14Z
author_fullname: 'Александр'
author_nickname: 'VinokurovAlexnader'
author_is_anon: false
---

<p>Вопрос "Есть кортеж из трех элементов. Назначить переменным a, b, c его значения".</p>
<p>У Вас ответ:<br>a, b, c = [1, 2, 3]</p>
<p>Но это список, а не кортеж. С кортежом будет вот так:<br>a, b, c = (1, 2, 3)</p>

Всего таких файлов 993. В шаблон заметки я добавил код для вывода комментариев:

{% assign comments = site.comments | where:'post', include.permalink %}
{% if comments.size == 0 %}
<center>Комментариев пока нет</center>
{% else %}
<center>Комментарии</center>
<div class="comments-block">
  {% for comment in comments %}
    <div class="comment-block">
      <p class="comment-lead">
        <small>
          <em>{{ comment.author_fullname or comment.author_nickname }}, {{ comment.date | date_to_string: "ordinal", "RU" }}</em>
        </small>
      </p>
      <div>{{ comment.content | markdownify }}</div>
    </div>
  {% endfor %}
</div>
{% endif %}

Получилось неоптимально, потому что на каждый пост происходит линейный поиск. В идеале нужно один раз построить словарь URL => список комментариев и затем брать оттуда. Но я не настолько хорошо знаю Jekyll и Ruby, чтобы это запилить.

Ради интереса проверьте страницы, где много комментариев, например про сервис IVI или про интервью. Лично мне результат нравится: чистенький HTML, минимум CSS, все лаконично. На текущий момент не учитывается структура, но технически это возможно: каждый комментарий знает ID родителя, и однажды их вывод можно улучшить.

Теперь главное: как сделать прием комментариев. Мне накидали советов, плюс я гуглил, и все сводится двум решениям: Гитхаб или self-hosted сервис.

Напомню, как работает Гитхаб: люди пишут комменты к какому-либо issue. Зная номер issue, легко выгрести комментарии GET-запросом, сгенерить HTML и вставить под заметкой. Выглядит красиво:

, но меня тревожат две вещи.

  1. Комментарии лежат в чужом сервисе, который может отвалиться из-за санкций или Роскомнадзора.
  2. Обязательна авторизация через Гитхаб — не у всех есть учетная запись.

Self-hosted-решения вроде Remark42 интересны, но вынуждают держать виртуалку, платить за нее и делать бекапы. Придется возиться.

Я придумал так. Пишем лямбду для Яндекс.Облака (на Кложе с компиляцией Граалем). Лямбда принимает POST-запросы с сайта. На сайте висит статичная форма с полем action=URL нашей лямбды. Отправить форму может любой желающий, даже тот, у кого нет учетки в Гитхабе, Твиттере, Инстаграме и так далее.

Получив запрос, лямбда создает pull request в репозитории блога. Для этого не нужен git: все возможности Гитхаба доступны в REST API. Pull request содержит новый файл с комментарием в папке _comments. Мне приходит письмо. Если норм, я нажимаю Merge, блог собирается и выкатывается новая версия.

Одновременно получается модерация: если кто-то написал дичь, я отклоняю PR, и делу конец.

Открыв PR, лямбда перенаправляет пользователя обратно в блог со словами “спасибо, ваш комментарий скоро появится”.

Вот такую штуку я хочу запилить. А пока что комментации работают только в Телеграме.