<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Лента комментариев</title>
        <link>https://evgenykuznetsov.org/posts/2020/indieweb-glue/</link>
        <description>Зачем хранить чужие данные, если есть IndieWeb? на DIMV - Лента комментариев</description>
        <generator>Hugo -- gohugo.io</generator><language>ru</language><managingEditor>evgeny@kuznetsov.md (Евгений Кузнецов)</managingEditor>
            <webMaster>evgeny@kuznetsov.md (Евгений Кузнецов)</webMaster><lastBuildDate>Sat, 19 Sep 2020 23:12:37 &#43;0300</lastBuildDate>
            <atom:link href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/comments.xml" rel="self" type="application/rss+xml" />
        <atom:link href="https://switchboard.p3k.io/" rel="hub" />
    <atom:link href="https://evgenykuznetsov.superfeedr.com/" rel="hub" />
    <item>
    <title>Индивеб</title>
    <link>https://evgenykuznetsov.org/posts/2021/indieweb/</link>
    <pubDate>Thu, 18 Mar 2021 20:58:11 &#43;0000</pubDate>
    <author>Евгений Кузнецов</author>
    <guid>https://evgenykuznetsov.org/posts/2021/indieweb/_https://evgenykuznetsov.org/posts/2020/indieweb-glue/_1080747</guid>
    <description><![CDATA[<p>А вот помните, сайты на narod.ru делали?.. Это тогда ещё называлось «домашняя страничка», и хорошим тоном считался тёмный фон, а шиком — менюшки с анимацией (и ещё тэг <code>&lt;marquee&gt;</code> модно было). А вместо комментов были гостевые книги на CGI, в которых толком не было авторизации. Это всё было очень мило, но не очень удобно: чтобы узнать, не опубликовал ли хороший человек чего-нибудь нового, нужно было идти к нему на сайт, да и за ответами в гостевые книги надо было нарочно заглядывать. Чуть позже придумали RSS — стало можно подписываться на сайты и сразу в одном месте видеть, у кого что нового. Оказалось настолько удобно, что живёт до сих пор, но к этому моменту уже появился ЖЖ, и владельцы домашних страничек массово мигрировали туда.</p>
<p>ЖЖ в русскоязычной Сети стал первой массовой социальной сетью, когда ещё словосочетания-то такого не было — «социальная сеть». Да, тут жёстко задавалась концепция блога с записями в обратном хронологическому порядке (многие в качестве титульной страницы делали «верхний пост»: датированный далёким будущим, чтоб всегда оставался первым в списке, он содержал общую информацию, какие-то ссылки и тому подобное), зато был сильно ниже порог вхождения (при желании можно было обойтись вовсе без знания HTML), были комментарии с авторизацией, и была возможность составить себе «ленту избранного», где в едином потоке читать все новые записи друзей и знакомых. Возможность общаться в Сети публично в реальном времени была и до этого (IRC и веб-чаты), возможность публиковать что-то надолго, чтобы потом можно было ссылаться и находить — тоже (домашние странички), но именно слияние этих возможностей дало совсем новый опыт, который пришёлся сетянам очень по вкусу.</p>
<p>Кстати, на пике своего расцвета ЖЖ был довольно открытой платформой. Да, чтобы пользоваться всеми функциями (например, читать закрытые блоги «только для своих») нужен был аккаунт именно в ЖЖ, но в принципе и читать понравившиеся журналы можно было через RSS, не заводя себе «ленту избранного», и комментировать можно было через OpenID… Потом, правда, в погоне за монетизацией всю эту свободу поукоротили. А каждая следующая социальная сеть, что-то упрощая (и тем расширяя аудиторию), приносила всё больше ограничений. Стало можно отмечать друг друга на фотографиях, но нельзя участвовать в дискуссии, не имея аккаунта. Стало можно выкладывать фото и видео вообще без технических знаний, но нельзя читать последовательно то, что сам выбрал, без посторонних включений и всякого «мы решили, что тебе вот это тоже понравится». Стало можно накладывать симпатичные фильтры на фото прямо в приложении, но нельзя в принципе смотреть публикации, не зарегистрировавшись. А самое главное — оказалось, что владельцы платформ в погоне за прибылью то и дело что-нибудь портят: меняют привычное поведение интерфейсов, перенастраивают алгоритмы, делают неудобный дизайн, вешают больше рекламы в самых неподходящих местах…</p>
<p>Это ещё с narod.ru началось: в какой-то момент стало неудобно загружать файлы, всё стало тормозить, а на страницах стали появляться некрасивые рекламные баннеры. Кто-то из-за этого подался на другие платформы, а кто-то решил, что проще немного заплатить и завести собственный сайт, где полностью распоряжаться дизайном, рекламой и всем остальным. Из ЖЖ, когда он начал портиться, тоже многие уходили «в свободное плавание», перенося блог на собственный сайт, где не забанят по надуманному поводу и не повесят баннер с рекламой бургеров в блоге вегетарианца. Даже выражение устойчивое появилось: «уйти на стендэлон» — в смысле, на «отдельно стоящий» блог, вне массовой платформы.</p>
<p>Но владельцам собственных сайтов тоже хочется того полезного, что дают социальные сети. Подписку-то можно и через RSS организовать, но хочется и комментариев, и лайки-репосты, и отметить друга в публикации, и ещё много всего. Как раз для этого владельцы собственных сайтов и придумали <em>индивеб</em>.</p>
<p>Собственно, <a href="https://indieweb.org/Main_Page-ru">индивеб</a> — это способ сделать из отдельных индивидуальных сайтов социальную сеть, точнее, использовать саму Сеть в качестве социальной. Или, правильнее сказать, это набор «социальных» инструментов<a href="https://evgenykuznetsov.org/posts/2021/indieweb/#fn:1">1</a>, которые можно использовать на своём сайте, если хочется. Плюс, конечно, <a href="https://view.matrix.org/room/!vRODLVURUpxrbkRiYp:matrix.org/">сообщество</a> людей, которые этими инструментами пользуются. Люди все разные, и сайты разные; в том и прелесть собственного сайта, что можно сделать его таким, как тебе нравится. И «социальные» функции каждому нужны свои, и на сайте у себя можно использовать только те инструменты, которые лично тебе нужны и полезны. Я, например, на своём сайте использую, фактически, всего три с половиной.</p>
<p>Во-первых, <a href="https://en.wikipedia.org/wiki/IndieAuth">IndieAuth</a> — способ авторизоваться с помощью своего сайта (в системах, которые это поддерживают). Пока это далеко не везде работает, в отличие от «войти с учётной записью Google» или «войти с помощью Facebook», например, но кое-где — да, я уже могу входить как «владелец evgenykuznetsov.org». Ну и OpenID, конечно, работает тоже.</p>
<p>Во-вторых, <a href="https://ru.wikipedia.org/wiki/HCard">hCard</a>. Информация обо мне самом у меня на сайте представлена специальным образом, чтобы эту «визитную карточку» можно было автоматически считать. Благодаря этому можно делать всякие <a href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/">забавные штуки</a>, но это больше тоже для того, чтобы представляться на других сайтах, а не для своего собственного.</p>
<p>Самое главное, конечно — <a href="https://evgenykuznetsov.org/webmentions/">вебменшены</a>. Это — едва ли не основной инструмент индивеба, способ сообщить другим сайтам, что на моём что-то о них написано (и наоборот). Именно так в индивебе устроены комментарии: я пишу коммент у себя на сайте, и мой сайт вебменшеном сообщает об этом комментарии тому, кому я отвечал; этот кто-то может у себя мой комментарий показывать или не показывать, но сам комментарий всё равно у меня на сайте, и никто, кроме меня, его не сотрёт и не отредактирует. Кстати, существуют сервисы, чтобы отправлять вебменшены и не имея собственного сайта: если, например, хочется прокомментировать вот этот вот мой пост, а сайта, который умеет в вебменшены, под рукой нет — пожалуйста, <a href="https://commentpara.de/">comment parade</a> в помощь.</p>
<p>Ну и ещё «половинка» инструмента из набора индивеба на моём сайте — это разметка, которая как раз работает в связке с вебменшенами. Сайт, который получит от моего вебменшен, сможет понять, что я имел в виду, о чём мой сайт сообщает: комментарий это, или просто «лайк», или человека в посте отметил (а не на конкретный его текст сослался). Я называю это «половинкой», потому что на моём сайте поддерживаются далеко не все принятые в индивебе типы публикаций. Ответы и «лайки» у меня есть, а вот репостов, например, нет — мне они без надобности. Поддержку календарных событий и ответов на них («приду»/«не приду»/«ещё думаю») я тоже пока не делал — как-то незачем было. Зато у меня есть отдельный тип публикации «перевод», который я же, собственно, и <a href="https://evgenykuznetsov.org/en/posts/2021/u-translation-of/">предложил</a>…</p>
<p>Кстати, новые фишки в индивебе появляются именно так: кто-то решил, что ему на сайте такое надо, сделал у себя, предложил остальным. Показалось нужным и удобным — можно сделать у себя так же, или ещё лучше, и тоже вынести на суд общественности. Те инструменты, которые в итоге прошли проверку временем по критериям нужности и удобства, как раз и составляют этот самый набор, называемый индивебом. Набор, надо сказать, на сегодняшний день уже весьма обширный, и постоянно расширяющийся; при желании в индивебе можно делать практически всё, что и в любой популярной соцсети. Но можно и пользоваться только тем, чем хочется: все люди разные, у всех сайты разные, это нормально.</p>
<p>В индивебе, кстати, принято сокрушаться, что обратная сторона вот этой свободы пользоваться только нужными лично тебе инструментами — высокий порог вхождения — ограничивает приток в индивеб широких народных масс. Это отчасти правда. Индивеб можно «прикрутить» почти к чему угодно: есть плагины для WordPress, есть вариант натянуть индивеб на Blogger, можно обходиться генератором статики, <a href="https://evgenykuznetsov.org/posts/2020/un-known/">как я</a>, но вот универсальной платформы для начинающих пока как-то не сложилось. Был Known, но теперь с ним <a href="https://evgenykuznetsov.org/posts/2020/tired-of-known/">сложнее</a>; сейчас на эту нишу вроде бы претендует Micro.blog, но к нему тоже <a href="https://evgenykuznetsov.org/posts/2020/microblog-is-bad/">есть</a> <a href="https://evgenykuznetsov.org/posts/2020/microblog-2/">вопросы</a>, так что простого рецепта типа «хочешь попробовать в индивеб — регистрируйся <em>вот на той платформе</em>, а дальше уж сам поймёшь, как и куда двигаться» на сегодняшний день не существует. Тем, у кого сайта пока нет, надо сначала определиться, как сайт будет выглядеть и как он будет устроен, а это — непростой выбор. Очень уж много разных вариантов, от простого аккаунта с прикрепленным доменом на том же <a href="https://micro.blog/">Micro.blog</a> до постройки <a href="https://marinintim.com/2019/indieweb/">по кирпичику с нуля</a>, что само по себе — интереснейшее занятие, не хуже выращивания орхидей или самогоноварения…</p>
<p>Впрочем, если сайт создаётся не только для того, чтобы общаться в индивебе, скорее всего, какое-то представление о том, какой он должен быть, и так есть. Кому-то по душе вести блог, кому-то хочется ту самую «домашнюю страничку» из девяностых, у кого-то будет фотогалерея, у кого-то — визитка с портфолио. Люди разные, и сайты у них разные. Индивеб открыт для всех.</p>
<p>Чем, собственно, и ценен.</p>
<ol><li>
<p>Метафора <span class="h-card"><a href="https://theadhocracy.co.uk/" class="u-url"><i></i> <span class="p-name">Мюррея Адкока</span></a></span>, <a href="https://theadhocracy.co.uk/wrote/one-year-in-the-indieweb">пост</a> которого подтолкнул меня к написанию этих вот букв. <a href="https://evgenykuznetsov.org/posts/2021/indieweb/#fnref:1">↩︎</a></p>
</li>
</ol>]]></description>
</item><item>
    <title>Jeannie лайкнул(а)</title>
    <link>https://twitter.com/nekr0z/status/1307413084219289600#favorited-by-1295515323567878144</link>
    <pubDate>Sat, 19 Sep 2020 21:02:48 &#43;0000</pubDate>
    <author>Jeannie</author>
    <guid>https://brid-gy.appspot.com/like/twitter/nekr0z/1307413084219289600/1295515323567878144_https://evgenykuznetsov.org/posts/2020/indieweb-glue/_853775</guid>
    <description><![CDATA[Jeannie лайкнул(а) <a href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/">https://evgenykuznetsov.org/posts/2020/indieweb-glue/</a>]]></description>
</item><item>
    <title>Ejitsu лайкнул(а)</title>
    <link>https://twitter.com/nekr0z/status/1307413084219289600#favorited-by-2886029872</link>
    <pubDate>Sat, 19 Sep 2020 21:02:48 &#43;0000</pubDate>
    <author>Ejitsu</author>
    <guid>https://brid-gy.appspot.com/like/twitter/nekr0z/1307413084219289600/2886029872_https://evgenykuznetsov.org/posts/2020/indieweb-glue/_853776</guid>
    <description><![CDATA[Ejitsu лайкнул(а) <a href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/">https://evgenykuznetsov.org/posts/2020/indieweb-glue/</a>]]></description>
</item><item>
    <title>Опять вебменшены (и не только)</title>
    <link>https://evgenykuznetsov.org/posts/2021/old-comments/</link>
    <pubDate>Tue, 31 Aug 2021 12:22:12 &#43;0000</pubDate>
    <author>Евгений Кузнецов</author>
    <guid>https://evgenykuznetsov.org/posts/2021/old-comments/_https://evgenykuznetsov.org/posts/2020/indieweb-glue/_1259518</guid>
    <description><![CDATA[<p>До недавнего времени вебменшены у меня на сайте показывались посредством <a href="https://github.com/PlaidWeb/webmention.js">webmention.js</a> (который я настоятельно рекомендую в качестве самого простого варианта тем, кто ещё не), но решение это всегда предполагалось временным — хотя бы потому, что не хочется быть привязанным к <a href="https://webmention.io/">webmention.io</a>. В качестве первого шага к независимости от последнего я этим летом как раз и переделал отображение вебменшенов. Внешне всё почти по-прежнему (так, собственно, и задумывалось), но «под капотом»…</p>
<p>Один из вопросов, немедленно возникающих при первых мыслях о написании своего webmention-endpoint: «Как хранить?» Сразу появляются мысли о базах данных, их преимуществах и недостатках, но, если мыслить в эту сторону, проще уж поднять у себя тот же webmention.io (он же опенсорцный) и не заморачиваться. Но у меня сайт на <a href="https://gohugo.io/">Hugo</a>, и тот факт, что всё хранится в текстовых файлах в одном git-репозитории, меня очень радует. Логичный вывод: вебменшены надо хранить так же.</p>
<p>Катализатором стал <a href="https://rowanmanning.com/posts/webmentions-for-your-static-site/">пост о внедрении вебменшенов в Hugo-сайт</a>: в самом деле, пусть сервер ходит время от времени на webmention.io и сохраняет новые вебменшены в JSON, а мы уж тут как-нибудь. Идея хранить их в отдельном файле в <code>/data/</code> была немедленно забракована: на то и <a href="https://gohugo.io/content-management/page-bundles/">Page Bundles</a>, чтобы хранить для каждого поста его содержание (в <code>index.md</code>) и полученные к нему вебменшены (в <code>webmentions.json</code>) в одной директории. Те вебменшены, что прилетели в адрес сайта в целом (например, <a href="https://indieweb.org/person_mention">person mentions</a>), можно хранить в <code>webmentions.json</code> прямо в директории <code>/content/</code>, и пока не отображать…</p>
<p>Автор упомянутого поста написал сохранение на JS и запускает с Netlify, но у нас тут никаких нетлифаев не водится, так что «сохранялка» нужна отдельная — благо, она <a href="https://evgenykuznetsov.org/en/posts/2020/webmention-backup/">уже была написана</a>, надо только добавить опцию для сохранения в соответствующие директории. Сказано — <a href="https://github.com/nekr0z/webmention.io-backup">сделано</a>, заодно и ещё полдюжины опций разных дописал, пока ковырялся (не знаю, нужны ли они кому-то, но в процессе отладки «само возникло» — пусть будет)<a href="https://evgenykuznetsov.org/posts/2021/old-comments/#fn:1">1</a>. Плюс — код, который отвечает за сохранение в поддиректории, наверняка пригодится потом, когда буду писать webmention-endpoint.</p>
<p>Первый затык: на части страниц (а в секции «Реакции» — почти на всех) только текст, и для такой страницы создавать Bundle было, конечно, лень. В Hugo содержимое страницы с адресом <code>https://evgenykuznetsov.org/posts/2021/old-comments/</code> может быть либо в <code>/content/posts/2021/old-comments.md</code>, либо в <code>/content/posts/2021/old-comments/index.md</code> (во втором случае в эту же директорию можно сложить картинки и прочее, что на этой странице потребуется — это и называется «Page Bundle»). Если я собираюсь хранить вебменшены в Bundle, первый вариант мне совсем не годится, а таких страниц у меня накопилось изрядное количество. Надо сохранить их все по второму варианту, каждую в своей поддиректории. Не вручную, конечно, а то всё лето и уйдёт — особенно с учётом языковых вариантов. Впрочем, у нас тут Linux: бери bash и <em>действуй</em>, как говорится:</p>



<pre><code><span> 1
</span><span> 2
</span><span> 3
</span><span> 4
</span><span> 5
</span><span> 6
</span><span> 7
</span><span> 8
</span><span> 9
</span><span>10
</span><span>11
</span><span>12
</span><span>13
</span><span>14
</span><span>15
</span><span>16
</span><span>17
</span><span>18
</span><span>19
</span><span>20
</span><span>21
</span><span>22
</span></code></pre>


<pre><code><span>#!/bin/bash
</span><span></span><span>set</span> -e

<span>wd</span><span>=</span><span>$(</span><span>pwd</span><span>)</span>

<span>if</span> <span>[[</span> <span>"</span><span>$1</span><span>"</span> !<span>=</span> <span>""</span> <span>]]</span><span>;</span> <span>then</span>
        <span>wd</span><span>=</span><span>"</span><span>$1</span><span>"</span>
<span>fi</span>

<span>for</span> x in <span>"</span><span>$wd</span><span>"</span>/*.md<span>;</span> <span>do</span>
        <span>case</span> <span>"</span><span>$x</span><span>"</span> in 
                *.ru.md<span>)</span>    <span>suffix</span><span>=</span><span>"ru.md"</span><span>;;</span>
                *.en.md<span>)</span>    <span>suffix</span><span>=</span><span>"en.md"</span><span>;;</span>
                *.md<span>)</span>       <span>suffix</span><span>=</span><span>"md"</span><span>;;</span>
                *<span>)</span>          <span>continue</span><span>;;</span>
        <span>esac</span>
        <span>name</span><span>=</span><span>"</span><span>${</span><span>x</span><span>%%.*</span><span>}</span><span>"</span>
        <span>if</span> <span>[</span> ! -d <span>"</span><span>$name</span><span>"</span> <span>]</span><span>;</span> <span>then</span>
                mkdir <span>"</span><span>$name</span><span>"</span>
        <span>fi</span>
        mv <span>"</span><span>$x</span><span>"</span> <span>"</span><span>$name</span><span>/index.</span><span>$suffix</span><span>"</span>
<span>done</span>
</code></pre>


<p>…и да здравствует Stack Overflow!</p>
<p>Дальше — проще. Убрал из шаблонов webmention.js, написал обработку JSON’а из бандла (во многом — тот же webmention.js, переведённый с JavaScript на язык шаблонов Hugo и доработанный «под себя»), «причесал» CSS (теперь знаю о CSS/SaSS сильно больше, чем в июне), написал новый шаблон для RSS-лент комментариев. Заодно разметил <a href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/">динамическую подгрузку</a> аватаров и имён; при этом вылезли баги в <code>indieweb-glue</code> (некоторые вещи не кешировались, хотя стоило, особенно 404-е ответы, в которых к тому же не прописывался CORS-заголовок) — починил тоже. Всё работает. Правда, теперь вебменшены отображаются не сразу после получения, а после следующей пересборки сайта, зато теперь я, при желании, могу легко организовать пре-модерацию, например.</p>
<p>Ой, так я ж теперь могу и старые вебменшены рисовать, те, которые ещё на Known получал, я ведь при переезде с Known на Hugo их сохранил, причём именно в JSON, в том же формате, в котором они отдаются webmention.io! Интересно, а что с аватарами за напасть? Ах, вон оно что: Known, принимая вебменшены, сохранял аватары у себя, и ссылки стоят на <code>evgenykuznetsov.org/service/web/imageproxy/</code>, которого больше и не существует вовсе. Надо эти ссылки поубирать. Не вручную, понятное дело: у нас ведь есть <code>jq</code> и особая магия <code>find</code> — хвала Дискордии за Stack Overflow!</p>
<pre><code>find ./ -type f -name "webmentions.json" \
    -printf \
        "jq -c 'del \
            (..|.photo?| \
            select(contains \
            (\"evgenykuznetsov.org/service/web/imageproxy\")?) \
            )' %p | \
        sponge %p\n" \
    | \
sh
</code></pre>
<p>А в каком формате у меня сохранены комменты из G+, ЖЖ и @дневников?.. Надо же, тот же самый JSON, вдохновлённый тем же webmention.io! Отобразим-ка и их тоже… Ага! У «лайков» в Google+ не было даты, и шаблон RSS-ленты об них «спотыкается»: Hugo охотно пытается распарсить дату из <code>nil</code>, но получает значение типа <code>error.Error</code>, которое дальше не обработать. Вписываем ещё одну проверку, и вот они, у меня на сайте — комменты, которым больше 15 лет! До чего же увлекательно перечитывать, особенно из тех времён, когда блог был куда более личным… Кого-то уже и по никам не помню, кого-то и в живых нет, с кем-то переписываемся-общаемся до сих пор, а кому-то тут же захотелось написать: «А помнишь?!.» Что ни говори, блогу, который ведёшь уже почти полжизни, да с комментами, никакой личный дневник и в подмётки не годится.</p>
<p>Следующим шагом буду webmention-endpoint писать.</p>
<ol><li>
<p>Кстати: если кто-то пойдёт этим путём и будет сохранять вебменшены в JSON, настоятельно рекомендую сохранять их в варианте pretty-printed (как, например, делает по умолчанию <code>jq</code>). Да, несколько сотен лишних байт на страницу, зато потом гораздо нагляднее в <code>git diff</code>. <a href="https://evgenykuznetsov.org/posts/2021/old-comments/#fnref:1">↩︎</a></p>
</li>
</ol>]]></description>
</item><item>
    <title>Всплывающие карточки и картинки для ссылок</title>
    <link>https://evgenykuznetsov.org/posts/2022/hovercards/</link>
    <pubDate>Thu, 01 Dec 2022 14:13:01 &#43;0000</pubDate>
    <author>Евгений Кузнецов</author>
    <guid>https://evgenykuznetsov.org/posts/2022/hovercards/_https://evgenykuznetsov.org/posts/2020/indieweb-glue/_1572465</guid>
    <description><![CDATA[<p>Мысль сделать на этом сайте всплывающие карточки на ссылках поселилась в моей голове уже довольно давно. От воплощения этой мысли в жизнь меня удерживали некоторые соображения (не в последнюю очередь — отсутствие нужных знаний и умений), но в конце концов оно, воплощение, состоялось.</p>
<p>Подтолкнула меня концепция <a href="https://maggieappleton.com/xanadu-patterns#1-visible-links">видимых ссылок</a>, которая показалась мне очень здравой. Как справедливо упоминает эта статья, в Википедии всплывающие карточки сделали не просто так. Я, конечно, далёк от мысли, что мой сайт можно сравнивать с Википедией, но сама идея дать читателю больше контекста с меньшими затратами весьма привлекательна, правда?</p>
<p>Одна из тех причин, по которым я до сих пор за всплывающие карточки не брался — мобильные устройства. На тач-скрине всплывающие карточки лишены смысла, а мне не хотелось делать на сайте что-то, чем нельзя будет пользоваться на телефоне или планшете. Не то, чтобы я был поклонником концепции «mobile first», скорее наоборот, но я всячески пытаюсь, работая над своим сайтом, не забывать и про мобильные устройства. Правда, <a href="https://evgenykuznetsov.org/git/">интерфейсом gitweb</a> на мобильном тоже не шибко удобно пользоваться, ну так и смысла пользоваться им на мобильном, откровенно говоря, немного, так что пусть уж будет. Википедия, опять таки, всплывающих карточек на мобильном не показывает; можно брать пример, пожалуй.</p>
<p>Со всеми этими мыслями я на этой неделе засучил рукава и открыл VSCodium. Очень помогло, что <span class="h-card"><a href="https://jamesg.blog" class="u-url"><i></i> <span class="p-name">capjamesg</span></a></span> как раз недавно <a href="https://jamesg.blog/2022/10/12/hovercards/">сделал</a> всю сложную часть (знаю, знаю, надо взяться-таки за JavaScript), так что мне осталась интересная. Понятно, что я не использую такой же бэкенд, как у Джеймса, и с этим пришлось как раз разбираться самому.</p>
<p>Откуда, собственно, брать информацию для всплывающей карточки? Логичнее всего — с самой страницы, на которую ссылка. По причинам, о которых я <a href="https://evgenykuznetsov.org/posts/2020/indieweb-glue/">уже писал</a>, собирать эту информацию и хранить у себя, как это делает Джеймс — не моё, так что очевидным решением стал снова <a href="https://indieweb-glue.evgenykuznetsov.org">indieweb-glue</a>. Понятно, пришлось сначала научить его возвращать информацию о страницах (а не только о людях). Брать же информацию на страницах было решено, для начала, из <a href="https://ogp.me/">Open Graph protocol</a>, благо он широко распространён, и на многих страницах в Сети соответствующие мета-тэги есть.</p>
<p>В <code>indieweb-glue</code> я добавил обработку этих мета-тэгов (заодно пришлось немного отрефакторить код), а скрипт Джеймса <a href="https://evgenykuznetsov.org/git/?p=hovercard.js.git">немного переделал</a>, чтобы он забирал информацию из <code>indieweb-glue</code>. Заодно научил скрипт работать с заранее определённым классом, а не просто с <code>&lt;article&gt;</code>, — так удобнее контролировать, где всплывающие карточки нужны, а где лучше без них. Добавил щепотку CSS, и всё заработало вполне удовлетворительно. Признаюсь, сам удивился.</p>
<p>Приятным бонусом стало то, что можно использовать этот же скрипт, чтобы «на лету» делать всплывающие карточки для сносок<a href="https://evgenykuznetsov.org/posts/2022/hovercards/#fn:1">1</a>; пожалуй, это меня порадовало ещё больше. Сноски меня вообще давно нервировали. С одной стороны, это — замечательный инструмент в арсенале писателя, незаменимый для сохранения плавности изложения без отвлечений и уводов от темы. С другой — в цифровом мире текст сноски сплошь и рядом оказывается за пределами экрана, и перемотка или переход по ссылке обычно чересчур сбивают с мысли. На бумаге-то достаточно просто посмотреть вниз; человек достаточно хорошо справляется с задачей возврата взгляда обратно в текст, чтобы просмотр сноски не сильно отвлекал от чтения. Возможность увидеть текст сноски во всплывающей карточке, кажется, — неплохой компромисс.</p>
<p>То, что получилось, пока далеко от идеала. Надо допилить CSS, а то карточки не всегда опрятно выглядят, особенно если картинка вертикальная. <code>indieweb-glue</code> надо научить брать информацию не только из Open Graph protocol; например, у страниц Википедии нет <code>og:description</code>, зато первый абзац самого текста — явно именно то, что должно быть в карточке. В планах и доработка скрипта: было бы здорово научить его распознавать особые случаи, и, например, для <a href="https://indieweb.org/person_mention">person mentions</a> заполнять карточку данными из H-Card.</p>
<p>Ну и, поскольку работа продолжается, за любые комментарии, советы и мысли о том, как лучше всё организовать, я буду очень признателен.</p>
<p>Пока писал этот пост, заметил, что для первой ссылки (та, что на статью <span class="h-card"><a href="https://maggieappleton.com" class="u-url"><i></i> <span class="p-name">Мэгги Эпплтон</span></a></span>) в карточке появляется нарядная картинка-обложка, сгенерированная, очевидно, автоматически. Я, разумеется, немедленно захотел себе что-то подобное для страниц, на которых нет «основной» картинки.</p>
<p>Вообще говоря, протокол Open Graph говорит, что свойство <code>og:image</code> — обязательное, то есть должно быть у каждой страницы. Конечно, искать для каждого поста (не говоря уж о твитоподобных заметках) подходящую (или хотя бы примерно годную) картинку слишком хлопотно. У этой проблемы есть три возможных решения: можно завести общую картинку для всего сайта, и ставить её «обложкой» на страницы, где своей картинки нет; можно генерировать картинки-обложки автоматически; наконец, можно просто плюнуть и на (значительной) части страниц не иметь картинки вовсе. Собственно, последний вариант нарушает протокол, но весьма распространён, и на моём сайте тоже до последнего времени использовался именно он.</p>
<p>Я поспрашивал (в <a href="https://matrix.to/#/!vRODLVURUpxrbkRiYp:matrix.org">чате русскоязычного индивеба</a>, само собой). Судя по всему, большинство (включая Мэгги) пользуется «безголовым» браузером <a href="https://playwright.dev/">Playwright</a>, разработанным для тестирования, чтобы автоматически открыть страницу и сделать её «скриншот» (который и становится картинкой-обложкой). Подход, надо признать, изобретательный, но к тому, как всё устроено у меня, не очень применимый. При дальнейшем погружении в тему нашлись специально для Hugo разработанная <a href="https://github.com/Ladicle/tcardgen">утилита</a>, а также изрядное количество инструкций по созданию таких изображений средствами JavaScript или Python. Инструкции, наконец, подтолкнули меня подумать головой, и в итоге я написал шаблон, который создаёт картинку автоматически для каждой странице, на которой «обложки» не хватает, прямо средствами самого Hugo.</p>
<p>Работает, хотя и в этом случае, конечно, доделок предстоит ещё много. Возможности обработки изображений в Hugo не безграничны, да к тому же меня очень сложно назвать «визуалом», и такие вещи всегда даются мне тяжело. Пока у меня совсем простенький скрипт, в котором задействованы только иконка сайта, информация об авторе и заголовок страницы, и нет никакого механизма, учитывающего длину заголовка, поэтому текст то и дело выезжает за пределы картинки или, наоборот, выглядит мелковато. Радует, что многие из имеющихся недостатков можно будет, при желании, со временем устранить, а скрипт доработать, чтобы использовал и другие данные о странице, для которой генерируется картинка. В любом случае, то, что получилось, лучше, чем ничего. По крайней мере, теперь на каждой странице есть свойство <code>og:image</code> — уже немало.</p>

<ol><li>
<p>Я иногда сносками злоупотребляю. <a href="https://evgenykuznetsov.org/posts/2022/hovercards/#fnref:1">↩︎</a></p>
</li>
</ol>]]></description>
</item></channel>
</rss>