Новый сайт для популярного медиа за 2 месяца
Давным-давно в далекой-далекой галактике появился проект The Bell, построенный на WordPress. Постепенно проект рос и развивался, добавлялись всевозможные галочки и тоглеры, накручивались фичи. Технический долг копился и тащил The Bell на тёмную сторону, а новые хотелки уже выходили за рамки возможностей CMS и превращали проект в колесо с костыликами вместо спиц. И тут редакция задумала обновить сайт и сделать редизайн новостной ленты.
«Что в этом сложного?» — видимо, подумали люди, не очень знакомые с техническими тонкостями, и обратились к нам за разработкой. Для нас же это поначалу напоминало анекдот: есть статичный макет, который совершенно неизвестно как должен меняться в зависимости от разных условий, и заказчик, который хочет увидеть новый сайт в работе меньше, чем через два месяца.
Как мы разбирались, что на самом деле нужно заказчику и какой должна быть админка, искали компромисс, чтобы уложиться в сроки, и реализовали новые фичи, расскажу под катом.
Исходные данные
The Bell — деловое медиа, которое начиналось с ежедневной e-mail рассылки. Сейчас это ещё и основной новостной сайт, и несколько спецпроектов с отдельными площадками.
Как вы поняли, сайт The Bell изначально был сделан на WordPress, что для стартапа вполне логично. WordPress — универсальная и простая CMS. И этим, по большому счёту, всё сказано. Она хороша для прототипирования и того, чтобы быстро стартануть; там можно реализовать всё, ну или почти всё. Но когда за несколько месяцев трафик вырос со 100 тысяч пользователей до миллиона, требовались большие усилия и кэши, чтобы WP и виртуалка, на которой он работал, не умирали. Поэтому сначала переехали на выделенный сервер и только спустя какое-то время занялись WordPress.
В подросшем продукте большее значение имеет то, сколько усилий потребуется для реализации стратегии развития и точно ли получится так же хорошо, как если делать с нуля под конкретную задачу. В случае «старого» The Bell каждая новая доработка делала реализацию всё более запутанной, громоздкой и непригодной для поддержки и рефакторинга.
Когда речь зашла о редизайне и полной переработке новостной ленты, стало очевидно, что проект перерос WordPress и пора разрабатывать специализированное решение. Новый макет с пятью новыми видами карточек, различными вариантами оформления материалов и возможностью управлять положением статьи в ленте на WP было бы не только сложно хорошо реализовать, но с этим потом было бы очень неудобно работать редакции, а поддержка и доработка для нас была бы полным кошмаром.
Для кастомной реализации мы выбрали связку Angular + Laravel, потому что оба этих фреймворка уже так или иначе были задействованы в отдельных модулях проекта. Для рассылок уже использовался модуль на Laravel, который отправлял письма через Mailchimp и собирал аналитику в нашей админке. И подпроект Bell.Club был ещё раньше сделан без участия WordPress на Laravel.
Что нужно сделать
Плиточную систему карточек материалов с возможностью выбирать оформление, ширину (на всю страницу, на половину, треть и четверть ширины), добавлять иллюстрации или фон и фиксировать позиции отдельных статей.
Для иллюстрации поместил в ленту статьи из нашего блога. The Bell пишут на острые социальные и политические темы, которые не хочется обсуждать в рамках данного поста.
А дальше мы вместе выясняли, что должно происходить со всеми остальными статьями: бесконечная ли будет лента, как она должна обновляться и куда будут попадать новые материалы, а куда уходить более старые.
Отдельно замечу, что заказчики — классные профессионалы в медиа, но среди них нет ни одного технического специалиста. Переложить задачу из картинок и разговоров в задачи для разработки нужно было нам самим. Работали в чистом виде по Agile и по ходу дела выясняли, что и зачем хочет клиент и что ему можно предложить по этому поводу.
На такого рода черновики мы ориентировались, проектируя админку.
Сроки. Ожидание vs реальность
Итак, мы подумали, что настало время отдавать техдолг, и настроились на большое переписывание. Мы же программисты — нас хлебом не корми, дай выбросить старый код и написать всё с нуля. Но получилось всё не совсем так.
Чтобы перевезти весь проект на новый стек, нужно было переписать всё, что связано с WordPress, а именно: фронтенд и бэкенд, админку и кучу всяких мелочей типа rss, метаданных, seo, которые в WordPress были реализованы плагинами. С учётом имеющихся ресурсов (в проекте было занято всего два разработчика) это заняло бы полгода. А заказчику новый дизайн нужен был к 1 апреля — на тот момент оставалось уже меньше двух месяцев.
Пришлось искать компромисс.
За что хвататься, чтобы всё успеть
В итоге решили разбить работы на несколько этапов и переезжать постепенно. Начали с фронтовой части и админки для управления лентой, а создание текстов писем и статей на первом этапе оставили в старой и привычной для редакции системе на WordPress. Конечно, это сделало работу сложнее, но позволило быстрее выкатить новую функциональность.
Бэкенд. Админка для размещения постов
У The Bell большая редакция, неудобное решение замедлит работу всего медиа. В первом собранном прототипе позицию фиксированного поста надо было просто указывать координатами вида: «Помести этот пост в третью строку на вторую позицию». Конечно, это был нежизнеспособный вариант, потому что редактору по сути требовалось самому помнить, как выглядит вся страница и что еще на ней зафиксировано.
Мы быстро поняли, что лучшим решением будет визуальный конструктор страницы. Такой, чтобы, примерно как на скриншоте выше, располагать статьи и виджеты, сразу видеть возможные варианты и результат. По сути, в конструкторе можно задать раскладку карточек на странице, которую мы называем темой (layout_theme). Тема — основная сущность, вместе со всеми зависимыми описывающая внешний вид новостной ленты.
Так как тема — это объект, к которому много обращений, её структура должна быть достаточно лаконичной, но при этом читаемой и понятной. У нас это набор горизонтальных объектов: линий или вложенных тем. Линия как объект определяет, сколько и какого размера блоков виджетов стоит в… в линии :) Например:
- 3 по 33,3%
- 33,3% + 66,6%
И прочие сочетания, кратные 33% и 25%.
Сами блоки виджетов бывают нескольких видов и описываются через набор полей:
- Новость — основной тип карточек, поля: цвет или бэкграунд подложки и, собственно, заголовок*.
- Цитата: цвет подложки, автор цитаты*, краткая информация об авторе и сама цитата*.
- Цифра дня: цвет подложки, цифра*, краткое описание*.
- Молния — карточка для важных и экстренных новостей — состоит только из заголовка*.
Поле имеет тип и указание на обязательность — * в списке выше. Также есть карточки, не связанные с постами, например, блоки подписки или сторонние посты.
Реализовать фиксирование любых постов внутри тем было легко за счет того, что линии — это одномерные структуры. Надо было лишь указать, на какой позиции в какой теме и линии пост зафиксирован.
Информация о закрепленных элементах хранится в json и выглядит примерно так.
{
"route_id": 1,
"theme_id": 1,
/* route_id - id пути в адресной строке и theme_id — id тем.
Они необходимы, потому что к одной теме может быть привязано несколько наборов закрепленных элементов. */
/* То есть например по пути / и по пути /tag/ тема одна и та же, но посты закреплены по-разному */
/* Список закрепленных элементов */
"items": [
{
/* Имя модели закрепленного элемента (тут может быть пост, форма подписки, рекламный блок или что угодно) */
"fixed_model_name": "Post",
/* ID айтема модели */
"fixed_model_id": 1,
/* ID линии. */
"line_id": 1,
/* Позиция в линии */
"position": 1,
/* Индикатор, повторяется ли это закрепление при повторных отображениях этой линии в бесконечной ленте */
"repeatable":0
},
...
]
}
В визуальном редакторе линии можно легко передвигать вверх-вниз и таким образом создавать новую тему.
Вот так это выглядит в админке на Angular:
В ней можно перетаскивать посты из списка всех постов и располагать их на макете. Естественно, можно попробовать разные варианты, прежде чем выбрать окончательный и применить его. Только после этого тема отобразится на клиенте, который получит структуру страницы со всеми вложенными элементами и их типами через API.
Преимущества нового бэкенда:
- Новая админка позволяет допускать меньше редакционных ошибок, связанных с человеческим фактором, потому что расположение постов удобно проверять в визуальном редакторе.
- Его быстрее дорабатывать и внедрять новые фичи, потому что мы хорошо знаем систему, которую сами и написали.
- Новый бэкенд стабильнее работает, то есть мы больше не теряем пользователей на простоях.
- Запросы теперь проще и работают быстрее, потому что идут к нашему серверу на Laravel и в специализированную БД, а не в универсальный WP. Скорость работы сайта для посетителей портала стала выше.
Публичная часть
Сделана на Angular и максимально переиспользует код из админки. На всех страницах с постами, кроме страниц типа «Команда», сделали бесконечную ленту, которая формируется за счёт повторения темы. Закреплённые посты показываются при прокрутке снова, если в админке для них задан параметр «repeatable».
Если из ленты перейти на детальную страницу поста, то там тоже будет тема, которая настраивается так же, как и все остальные темы, и также бесконечная. Например, сейчас первую линию занимает сам пост, дальше блок три по 33,3% и снова статья. И при этом, в зависимости от того, какая статья из бесконечной ленты сейчас на экране, меняется url. Кроме того, в текст поста, который приходит с бэкенда в виде HTML, можно встроить Angular-компоненты, например, форму подписки на рассылку.
Все темы на сайте The Bell свёрстаны на гридах.
Релиз и результаты переезда
За два месяца у нас, конечно, получилось то ещё чудовище Франкенштейна. Мы написали API для переезда на новый стек, но посты пока что создаются по-прежнему в админке на WP, синхронизируются с базой данных, и тогда уже в новой админке можно управлять их положением на странице.
Как бы то ни было, к оговоренному сроку фронтенд был готов и мы начали постепенно раскатывать его на пользователей, наращивая трафик. Это было нужно, чтобы отловить возможные баги, пока они не повлияли на большое число пользователей, и наш отдел эксплуатации легким движением команд в консоле настроил нам это.
Даже такой монстрик позволил, во-первых, за короткий срок решить задачу бизнеса, а во-вторых, существенно снизить нагрузку как на БД, так и на CPU. Если до переезда сайт мог упасть из-за крайне медленных запросов в таблицы WP, где все метаданнные (например, категории, тэги, картинки и т.д.) находятся в одной и той же таблице, а также в одной таблице хранятся посты и десятки (!) ревизий этих постов. То после переезда проблем с базой не было ни разу.
To be continued
Новый дизайн мы выкатили примерно полгода назад и теперь в режиме небольших доработок постепенно переносим все инструменты на новый движок и дописываем админку. Как это обычно бывает, продуктовые фичи отнимают почти всё время и они на виду, а внутренние доработки не всегда видны со стороны заказчика, но нужны для дальнейшей миграции и развития. Поэтому мы стараемся разгребать техдолг. В ближайших планах внедрить ssr и фиды на нашем бэкенде (сейчас это все ещё на стороне WP) и перевезти редактирование постов на новый редактор. А также довести до продуктового использования заложенную механику вложенных тем.
Послесловие
Закончить статью хочу нетехническими выводами о пользе гибкого подхода, в которой мы еще раз убедились на примере этого проекта:
- Если ваша самая оптимистичная оценка срока разработки в 3–5 больше, чем то, что нужно бизнесу, то это НЕ значит, что ничего не получится. Необходимо искать альтернативные варианты.
- Большой переезд — это не обязательно два года работы. Можно реализовать самое необходимое в новых модулях (или сервисах) на новом стеке и постепенно переносить старое и допиливать фичи. Это, может быть, не самое удобное и простое решение для разработчиков, но оно рабочее, способствует гибкой разработке и не заставляет пользователя резко отказываться от привычных инструментов.
- В условиях сжатых сроков большое значение имеет организация работы. Такие, казалось бы, очевидные моменты, как налаженная коммуникация, быстрое решение блокеров и слаженная работа кросс-функциональной команды могут быть решающими.
- Мы пишем код не для себя, а для того чтобы он решал бизнес-задачи. Лучше потратить время и разобраться в нуждах пользователя (для нас это не только посетители сайта The Bell, но и редакция медиа), чем написать идеальный код, которые делает что-то не то.
- Взять и сделать сразу всё идеально в реальном мире, к сожалению, невозможно. Вам всегда будет хотеться что-то переделать и улучшить. И это хорошо, потому что помогает не стоять на месте.
Мы в ITSumma довольно много работаем с медиа, накопили опыт и в разработке с нуля, и в поддержке и доработке проектов на разных стеках. Напишите в комментариях, если интересна эта тема, — постараемся поделиться собранными граблями и удачными решениями в новых постах. И не стесняйтесь задавать вопросы :)