Как появился сайт

Раз уж я потратил на него столько времени, почему бы не потратить еще немножко на рассказ о том, как он делался и что у него внутри.

Короткая версия 

Сайт создается в Hugo. Используется сильно перепиленная тема Doks версии 0.5. Основной фреймворк — Bootstrap; мелкие детали понадерганы откуда попало. Особо отмечу прекрасный сайт Hugo Codex. Статистика посещения сайта ведется сервисом GoatCounter.

С этими оговорками можно считать, что сайт сделал я.

Длинная версия 

В июне 23-го я приехал в Техут, рассчитывая прожить там три недели. При мне был огромный рюкзак, но не было паспорта — паспорт остался на рассмотрении в испанском визовом центре. Я заселился в дом на горе и вскоре оказался в непривычном положении.

Впервые за всю историю наблюдений мне стало нечего делать. Управление мастерскими требовало некоторого внимания, но не занимало дни целиком; вернуться в Тбилиси я не мог, потому что не додумался сделать второй загран; открывать мастерскую в Ереване не хотелось, потому что там стояла адская жара; возвращаться в Россию не хотелось тем более.

Я честно отгулял десятки километров по окрестным лесам, горам и монастырям, но этого не хватило. Пришлось найти какое-нибудь максимально утомительное дело, каковым и стала разработка сайта.

Почему делал сам 

Потому что много лет не мог закончить фразу “мне нужен сайт, который…” Который что? В голове стоял густой туман. Даже если бы ко мне пришел лучший веб-дизайнер на свете, я бы не смог поставить задачу.

Хотелось, например, перенести посты из ЖЖ, подальше от вот этого всего:

Но просто перенести их можно было разве что для публикации под заголовком “Старое говно”. Требовался не столько перенос, сколько ремастеринг — а его мог сделать только я, да и на этот счет были сомнения.

Крохотный сайт-лендинг меня тоже не привлекал: с его задачей справлялись соцсети.

Волонтерски настроенные читатели-программисты не раз предлагали мне перенести статьи из ЖЖ на отдельный адрес, прикрутив сбоку телефон и адрес мастерской. Именно этим объясняется периодическое появление таких постов:

ШОК! Гитарный мастер делал себе сайт 12 лет!

Михаил Парфёнов, известный под юзернеймом Slider, прошел дальше всех: в смысле, он собрал ЖЖшные статьи через скрипт, выложил их на новом месте, а потом прислал мне ссылку на практически готовый сайт и спросил, что поправить. О-хре-неть! На дворе был 2018-й.

Я ответил “круто, скоро напишу, что поправить” и пропал.

Если придерживаться этой тактики достаточно долго, от вас отвернутся даже самые великодушные люди.


Была еще одна интересная проблема, которую трудно описать. Я мечтал о масштабном проекте, который станет основной моей платформой для распространения идей. А к выбору платформы надо подходить тщательно.

Поучительная история о курсиве 

В 2013-м я перенес личный бложик из ЖЖ на ВК. Он тогда был во всех отношениях классной соцсетью, но все же соцсетью — поэтому в постах нельзя было использовать курсив и формат текст-картинка-текст, знакомый по ЖЖ. Механизм публикации лонгридов, где все это было, прикрутили много лет спустя и без всякого уважения: промотать мимо такого лонгрида в ленте — раз плюнуть.

Мне пришлось привыкнуть к формату короткого сырого текста, все иллюстрации к которому ссыпаны кучей в подвале. В этом жанре я добился некоторого успеха; в нашем паблике сейчас 10 тысяч подписчиков, и было бы гораздо больше, если бы я начал его вести сразу же, а не в 2018-м.

Тем не менее, я осознавал, что характерная для соцсетей скованность в средствах самовыражения ограничивает не только качество текста, но и мышление его автора. Возможно, это не у всех так — но мое мышление от долгой работы с соцсетями точно пострадало. Нынешний возврат к регулярному написанию лонгридов воспринимается… ну, как избавление от хронической боли, наверное.


Таким образом, средством самовыражения должен был стать не только контент, но и сам сайт. Мне хотелось иметь гибкую, изменчивую, не вполне предсказуемую с точки зрения читателя структуру, которую я смогу формировать под свои нужды на лету; сделать не просто цифровой сад, а цифровой тропический лес.

Поэтому я решил, что буду делать все сам. Выбор пал на движок Hugo.

Почему Hugo 

Короткий ответ: потому что он позволяет строить очень сложные структуры на очень простом фундаменте.

Hugo является генератором статических сайтов. Это относительно новый тип движков, о нем мало кто слышал даже среди энтузиастов. Более того, первое знакомство с принципами работы Hugo часто заканчивается недоумением: вы че, правда делаете сайты, как 20 лет назад?..

Это и так, и не так.

Результатом работы хьюго действительно является тупейший статик-сайт: HTML, CSS, немного JS и все.

Отличие от хтмл-редакторов начала века — в том, как этот результат формируется. Хьюго собирает страницы по кусочкам, ориентируясь на структуру директорий проекта и метаданные контент-файлов. В процессе он подтягивает данные из внешних источников, форматирует картинки, переводит маркдаун в HTML и обрамляет его всякими менюшками с помощью гибкой системы шаблонов.

Непонятно? Давайте я покажу на примере.

Пример: автокарусель 

Вот как устроена директория, из которой собирается страница /workshops/formershops/:

Внутри ее бандла — файл index.md и папка с изображениями. Изображения рассортированы по принадлежности к каждой из наших прошлых мастерских (например, gb — это Гитарбанк). Вне этой сортировки — только файл sk2_end.jpg.

Заглянем в index.md:

Начинается он с метаданных (Front Matter в терминологии Hugo). В данном случае они очень просты:

  • weight задает позицию страницы, например, в меню. Значение 100 — самое большое среди всех страниц этого раздела, поэтому “прошлые мастерские” — последний пункт в боковом меню /workshops/.

  • toc определяет, показывается ли на странице содержание. Оно формируется автоматически, по <h*>-тэгам, но в мелких статьях я обычно его убираю. У этой статьи оно есть (если вы с компьютера — то справа, а если с телефона, то сразу под заголовком).

Все прочие строки комментариев не требуют. Идем дальше.

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

Самое интересное тут — не маркдаун, а дополнительные шаблоны. Вот две выделенные на скриншоте строки:

{{< csf id="9" >}}img/lado{{< /csf >}}
<p></p>

Пустой параграф снизу нужен только для правильного отступа (иногда отступ мне не нужен, поэтому он не формируется автоматически). А вот верхняя строка - это вызов шорткода, лежащего в папке /layouts/shortcodes/csf.html. При вызове ему передается значение img/lado, являющееся, как нетрудно догадаться, адресом директории с фотками нашей мастерской на Ладо Асатиани.

CSF означает Carousel Folder. Заглянем в этот шорткод:

Вопреки расширению файла, внутри используется не только html, но и код Go Templates. Вот первые строки:

{{ $allImages := $.Page.Resources.ByType "image" }}

Все картинки, расположенные в директории текущей страницы, обозначаются переменной allimages

{{ $imagesInFolder := $allImages.Match (printf "%s/*" .Inner) }}

… после чего из них отбираются только те, которые лежат в папке img/lado/. Результат записывается в переменную imagesInFolder.

Но самая красота начинается дальше.

{{ range $index, $img := $imagesInFolder }}
    {{ $img := $img.Resize "1200x q100 Lanczos" }}
    {{ $img := $img.Fill "1200x900 q85 Lanczos" }}
    ...
    <img src="{{ $img.RelPermalink }}"...

Каждое из отобранных изображений ресайзится до 1200 на 900 пикселей c сохранением пропорций. Затем каждое из них показывается внутри обычного <img>-тэга.

Для доступа к оригинальным версиям достаточно ткнуть на картинку.

Столько возни — а в чем профит? Да в том, что эти папки теперь — фотоархив наших старых мастерских. Я просто кидаю в них все, что нахожу, и движок моментально подхватывает новые картинки, делает их форматированные копии и вставляет в карусельки на странице автоматически. Вот, только что закинул новую картинку все в ту же папку, посвященную Ладо Асатиани:

Полсекунды — и она появилась на локальной копии сайта:

Мне остается только раскладывать фотки по директориям.


Таким же образом устроен и весь остальной сайт: простые правила и шаблоны в результате своего взаимодействия создают очень сложные структуры. Я не пересчитываю статьи по тегам в боковом меню раздела /articles/, и не вписываю имена наших мастеров в /workshops/team/ — все это движок делает сам, был бы нужный код в шаблонах.

Код я частично брал из разных репозиториев, частично генерировал с помощью ChatGPT, частично писал сам. Мне все еще кажется, что я ни черта не понимаю в программировании, но степень моей невинности сейчас и летом 23-го существенно различается.


Сгенерированный сайт никакого исполняемого кода уже не содержит. От сервера требуется только показывать посетителю статические страницы, поэтому хостить такой сайт можно хоть на яндекс-диске (на самом деле нет, но почти).

Еще одно преимущество — возможность собирать сайт из исходников прямо на удаленном сервере. У меня это работает через связку GitHub и Render. Дописав очередную статью на своем ноутбуке, я отправляю ее в репозиторий на гитхабе. Рендер следит за репозиторием, и при наличии изменений запускает генерацию сайта заново. Через несколько минут новая версия оказывается в онлайне.

Динамического контента нет. Но не больно-то и хотелось. В тех случаях, когда он требуется на хьюго-сайте — например, для каментов, — его обычно подтягивают через скрипт с внешнего сервера.

Тема Doks 

Вот ее я, кажется, не рекомендую, но мне сложно судить: когда я начинал работу над сайтом, актуальной версией была 0,5, а на момент написания этой статьи уже вышла 1,3. Автор сообщает, что там исправлены многие вещи, которые раздражали меня в старой версии, но непохоже, чтоб все :-)

Как только я малость освоился с Bootstrap, SCSS и Go Templates, я начал перепиливать Doks под свои нужды. Устранял баги, правил шаблоны, добавлял новые стили… Большую часть изменений я уже не вспомню; несомненно лишь, что клонировать йибуй, просто накатив на свой проект любую из версий Doks, невозможно. Публиковать свой форк я не планирую.

Я бы не смог сделать такой сайт с нуля, поэтому Doks все равно принес много пользы, несмотря на баги. Автору я очень признателен.

Перенос статей 

После создания основных шаблонов я начал переносить на сайт свои посты из ЖЖ.

Казалось бы, че там делать? Скачиваешь со страницы все картинки скриптом, копипастишь текст, и все. Более того, хьюго поддерживает html в контент-файлах, поэтому я мог бы просто копировать содержимое поста из окна редактора (в ЖЖ, с некоторыми оговорками, для разметки применяется именно html).

Я мог бы так поступить, но не стал — потому что и тексты, и картинки оказались не але.

Картинки были просто мелкие. В 2011-м году казалось, что 800 пикселей по ширине — это очень много. Ретина-дисплеев еще не было. Быстрого мобильного интернета тоже не было, что заставляло бережнее относиться к трафику, чем сейчас.

Поэтому значительная часть статей в ЖЖ была проиллюстрирована картинками с разрешением 640 на 480, и даже в 2021-м я выкладывал картинки шириной 900. Это 450 на ретина-дисплее. А ширина колонки со статьей — 700. Маловато.

А тексты… Знаете ощущение, когда находишь свои старые записи и думаешь господи какой ужас? В случае постов в ЖЖ это ощущение наступало по двум фронтам: помимо множества фактологических ошибок меня расстраивало качество самого текста.

Тащить этот шакальный кринж на свой сайт было недопустимо.

К счастью, у меня сохранился архив фотографий. Это позволило раскопать оригиналы жжшных картинок, заново их кадрировать, обработать и пожать до 2000 по ширине, а потом уже скармливать движку. Звучит нехитро — но в некоторых статьях более семидесяти фотографий, а самих статей больше сотни…

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

Переписывание статей и обработка фотографий отняли много времени. Зато качество материалов на сайте теперь приемлемое.

Картинки и трафик 

Джипег 2000×1500 весит около 600 кб. Пресловутые семьдесят джипегов, соответственно, — 42 мегабайта. Это дофига! Читатель, заходящий на йибуй с десктопа, подключенного к интернету витой парой, такого трафика не заметил бы… но другой читатель, зажатый в электричке до Долгопрудного с телефоном в руках, охренеет столько грузить по воздуху.

Поэтому йибуй бережет ваш трафик:

  • Все крупные картинки, которые вы видите в статьях, имеют не более 1400 пикселей по ширине;

  • Также они сконвертированы в .webp, что уменьшает их размер примерно на четверть;

  • Все картинки, кроме выложенных в карусельках, имеют атрибут loading="lazy", поэтому подгружаются не сразу, а по мере скроллинга;

  • Сайт подсовывает вам картинки разных размеров в зависимости от ширины окна браузера. Помимо стандартной ширины 1400 имеются размеры 720 и 1080. Если вы заходите на сайт с небольшого мобильника или старого ноута с низкой плотностью пикселей, вам покажут как раз 720 — что очень разумно, потому что отличить их от 1400 без зума у вас все равно не получится.

Оригиналы шириной 2000 все еще доступны по клику или тэпу на саму картинку.

Поддержка браузеров 

Я регулярно открываю сайт в Safari с десктопа и в Chrome с десктопа и с мобилы. Ни разу не проверял, как сайт выглядит в Firefox, но а) им пользуется 3% людей, и б) маловероятно, что именно там что-то расползлось.

Если ваш браузер не поддерживает webp и/или атрибут srcset, то с картинками будет беда. Но такое старье использовать — это надо постараться. В остальном сайт не требователен, и даже без джаваскрипта более-менее работает.

Если нашлись баги, пишите в телегу @mux22. Опечаток это тоже касается, кстати. Потом, возможно, прикручу штуку с контрол-энтером.

Результаты разработки 

  • Я задолбался. Это самый сложный проект в моей жизни; изготовление басов и рядом не стояло.

  • Отработана рутина публикации текстов: я привык к VS Code и с большим уютом пишу статьи с маркдаун-оформлением. Для меня это всегда было самое сложное — привыкнуть к новой среде.

  • Список языков, фреймворков и технологий, с которыми я познакомился: html, yaml, toml, css, sass, bootstrap, markdown, go templates, hugo, npm, git, automator. Было очень интересно!

  • Йибуй стал самым большим сайтом о гитарном деле на русском языке. Основной вклад, правда, принадлежит старым статьям из ЖЖ, но они, как я уже указывал, не совсем старые. Да и я еще накидаю сотню-другую новых.

  • Есть надежда, что клиенты перестанут путаться в наших мастерских и соцсетях. У нас они еще и называются везде по-разному, иначе скучно. Наличие общей информации по всем мастерским, их графикам, адресам и телефонам — ценно. Давно пора было.

  • Я наконец отдал должное своей команде. Наши мастера и менеджеры чрезвычайно круты. Страничка /workshops/team/ — первый камень памятника, который я хочу им поставить.

  • Последнее древнее проклятие, лежащее на нашей мастерской, снято. Предыдущими были Отсутствие Малярки (сделали ее в 2023) и Проклятье Третьего Рабочего Места (побороли в 2018).

С интересом смотрю в будущее.

МТ
февраль 2024-го, Тбилиси