Искусство сомневаться

В начале Осени

В этой главе мы увидим основные идеи, стоящие за новой CMS (кодовое имя «Осень»). Из этого хаотичного наброска вырастет цельное представление о том, что мы хотим реализовать. Основная идея — создать простую в обращении и обслуживании, продуманную и отполированную систему в духе Ghost и Craft, но добавить больше инструментов редактирования и представления контента. Это позволит использовать CMS изданиям, требующим большего, чем просто блог.

Одновременно мы хотим избежать хаоса и тяжёлого наследия прошлого, которым страдает WordPress. Вопрос кастомизации должен быть продуман с самого начала, но конкретная форма требует дополнительного исследования.

Существующие решения

WordPress

Ghost

Он классный, но в нём не хватает нескольких компонентов:

  1. Публикации на нескольких языках
  2. Шаблонов для разных видов публикаций, который могут потребоваться онлайн-изданию (новости, интервью, эссе, репортажи, около-академические статьи)
  3. Интеграции с соцсетями, не распространёнными на Западе
  4. Интеграции с платёжными системами, не распространёнными на Западе

Craft CMS

Craft CMS

Публикация, ключевой элемент

Схема публикации

Метаданные

Авторы. Нам нужна гибкая настройка авторов — их может быть несколько и они могут отличаться между версиями на разных языках.

Переводчики. Указывать авторство перевода это хороший тон.

Иллюстраторы. Иногда иллюстрации могут быть не менее важной частью публикации.

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

Тэги. Категоризация публикаций.

SEO. Заголовок, описание и микроформаты для поисковиков и социальных сетей.

Связи между публикациями. Публикации могут быть объединены в серии или представлять собой онлайн-дискуссию.

Даты. Дата создания, последнего изменения и публикации.

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

Документ

Сам документ должен хранится в формате, который отвечает нескольким требованиям:

Компоненты системы

Редактор, в котором хочется писать

Цель создать редактор, который будет использоваться напрямую, а не просто «написал в другом месте и скопировал сюда».

Базовое форматирование

Редактор должен поддерживать базовое форматирование (курсив, полужирный, таблицы и т.д.). Администратор должен иметь возможность настроить доступные редактору возможности форматирования для сохранения общего стиля издания. К примеру, отключить выделение разными цветами или ограничить палитру цветами бренда.

Блочное редактирование

Документ разбит на сегменты, которые инкапсулируют свой контент в универсальный контейнер. Внутри может быть параграф текста, заголовок, изображение, произвольный HTML и т.д.

Виды сегментов
  • Параграф
  • Разделитель
  • Закладка (Ссылка с изображением и предпросмотром, аналогичная preview в соцсетях)
  • Разделение на публичную/закрытыю часть
  • Call to Action/Ad
  • Email content
  • Callout/Hero
  • Header
  • Signup
  • Toggle
  • Video
  • Audio
  • File
  • Product
  • HTML
  • Markdown
  • Картинка
  • Галерея
  • Кнопка/Группа кнопок
  • Вставки
    • Youtube
    • X
    • Unsplash
    • Vimeo
    • CodePen
    • Spotify
    • SoundCloud
    • Telegram
    • Custom

Сегмент можно перемещать по документу. Сегмент можно расположить в зоне шаблона.

Шаблоны

К документу можно применить шаблон, который описывает какие сегменты могут быть в документе и как они расположены. К примеру, шаблон «Интервью» содержит в себе сегменты «Вопрос» и «Ответ» помимо сегментов по умолчанию, таких как параграф.

Выбор сегмента в шаблоне интервью
Выбор сегмента в шаблоне интервью

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

Шаблон в вёрсткой в две колонки
Шаблон в вёрсткой в две колонки

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

Предпросмотр

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

Вопрос Markdown

В Ghost можно вставить Markdown отдельным блоком, который будет распознан и трансформирован в HTML. Хотим ли мы сделать также или стоит создать отдельный режим редактирования для Markdown, в котором редактор будет трансформировать Markdown на лету (как, к примеру, в Obsidian)?

Всё для перевода

Перевод сайта должен быть всеобъемлющим, все компоненты системы должны быть доступны для локализации.

Перевод интерфейса

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

Перевод контента

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

структура тэгов на разных языках

Перевод публикаций

«Осень» должна предоставлять удобный интерфейс для перевода контента. Каждый перевод это отдельный документ со своими авторами, переводчиками, иллюстраторами и т.д., датами публикации и т.д. Как указано выше, каждая языковая версия публикации должна быть отдельной записью в БД и иметь общий уникальный идентификатор.

Переводы должны быть интегрированы в процесс работы и интерфейс.

Списки сущностей должны иметь фильтр по языку.

список публикаций отфильтрованных по языку

Каждая публикация должна ясно показывать, на какие языки она переведена.

языки на которые переведена публикация

Создание перевода должно быть легко доступно из интерфейса публикации.

интерфейс создания перевода

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

две версии перевода рядом друг с другом

Предложение автоматического перевода с возможностью редактирования

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

Интерфейс с оригиналом, переводом и предложенным автоматическим переводом

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

Инструменты редактора

Для эффективной работы онлайн-издания CMS должна поддерживать гибкий рабочий процесс, где каждая публикация может проходить через несколько этапов перед публикацией.

Процесс производства и публикации

Публикация начинается с черновика, который доступен только в административном интерфейсе.

Далее черновик может быть переведён в статус "готово" и ожидать публикации. Здесь нам нужен интерфейс для обсуждения и редактуры материала, который включает в себя:

  1. Комментирование, привязанное к отдельным разделам материала
  2. Обсуждения (треды) по каждому комментарию
  3. Предложения изменений, которые могут быть приняты или модифицированы автором

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

Статусы публикации:

  1. Черновик. Назначается при создании нового материала
  2. Готов. Назначается, если материал требует этапа редактуры и не публикуется немедленно.
  3. Ожидает доработки. Назначается, если редактор вернул материал на доработку автору.
  4. Ожидает публикации. Назначается, если материалу назначено время публикации в будущем.
  5. До звонка/по триггеру. Назначается, если материал должен быть опубликован по триггеру.
  6. Опубликован. Назначается, когда материал опубликован в открытый доступ.
  7. Отозван. Назначается, когда ранее опубликованный материал отозван.

Описанный выше порядок работы это "программа-максимум". Администратор сайта должен иметь возможность выбрать несколько вариантов порядка работы — "полный", "упрощённый" или какую-либо ещё комбинацию статусов.

Доступ для внешних авторов

CMS должна иметь возможность предоставить доступ к редактированию одной публикации для внешнего автора и последующего обсуждения при редактуре. Для этого может потребоваться специальная роль и возможность авторизации через внешние источники, которые поддерживают OAuth и аналогичные механизмы.

Совместная работа

Система должна поддерживать одновременное редактирование несколькими пользователями, сохраняя и совмещая изменения в виде CRDT.

Расписание публикаций

«Осень» должна предоставлять интерфейс для контент-плана, в виде календаря с запланированными публикациями и временными слотами.

Версионирование

Каждое изменение статуса публикации создаёт новую версию. Система должна предоставлять механизм для просмотра истории версий и изменений между версиями.

Доставка контента

HTML страницы

JSON API

RSS и Atom

Интеграции

SEO

Микроформаты

Аналитика

Платежи и подписки

Роли, права и доступы

Структура данных

Публикации

Ресурсы

Рендеринг HTML и API

CMS должна предоставлять серверный рендеринг HTML и REST API — публичный для отображения контента используя фронтенд пользователя и закрытый за авторизацией для административной панели.

Возможно, нужно предусмотреть возможность отделить модуль рендеринга HTML и запустить его вместе с веб-сервером на Edge-воркерах и подобных системах, получая при этом контент из базы данных через API. Насколько это востребованный и полезный функционал пока неясно.

Федерация

ActivityPub

ATProto