Аналіз WYSIWYG-редакторів на відповідність ключовим вимогам

Контекст

Задля спрощення досвіду створення HTML-шаблонів, необхідно надати адміністратору візуальний WYSIWYG-редактор, який дозволить формувати статичний шаблон та визначати місця для вставки динамічних даних визначати конструкції циклів, умов, тощо.

Функціональні сценарії

  • Створення HTML-шаблонів для генерації витягів з реєстру

  • Створення HTML-шаблонів для генерації поштових повідомлень

Шаблонізація

Опис вимог до шаблонізаторів та розглянутих варіантів знаходиться на сторінці Аналіз технологій шаблонізації HTML-документів на відповідність ключовим вимогам.

Вибір WYSIWYG-редактора шаблонів

Ключові функціональні вимоги до візуального редактора

  • Можливість завантаження зображень в inlined формі

  • Можливість використання зображень за URL

  • Можливість використання чітко визначених наборів стилів для формування та перегляду шаблонів

  • Використання чітко визначених css класів стилів в кожному наборі стилів задля підтримки темізації

  • Можливість окремої стилізації для шаблонних підставлених значень (включаючи репорт)

  • Підсвічення вставок шаблонізації при редагуванні (to be discussed)

  • Функціональність шаблонізації:

    • Можливість вибору ключа значення (назви змінної) прі вставці значення

    • Візуальна категоризація та вибір необхідних шаблонних тегів/атрибутів для використання

  • Можливість використання таблиць

    • look and feel:

      • Colgroup з можливістю коригування ширини колонок у відсотках

      • Товщина границь включно з нульовою

      • Alignment всередині комірок

    • Data source access requirements (action: ask for most complex report)

  • Два режими для редагування шаблону: WYSIWYG та вихідного коду, та синхронізація обох варіантів

  • Робота з посиланнями

    • href повинен підтримувати темплітизацію та підставляння значень шаблонних змінних

    • mailto посилання

Ключові нефункціональні вимоги до візуального редактора

  • Централізація контенту (включно із зображеннями)

  • Шаблонізація для репортів та mail листів

  • Додаткові класи для комірок таблиць

Розглянуті WYSIWYG-редактори

  • TinyMCE

  • CKEditor

  • Quill

  • Draft.js

  • Slate

Аналіз WYSIWYG-редакторів на відповідність вимогам

В рамках функціональних та нефункціональних вимог у цій таблиці використовуються позначки для оцінки ризику досягнення (мети). Позначки виглядають так:

  • S - малий ризик досягнення

  • M - середній ризик досягнення

  • L - великий ризик досягнення

  • XL - занадто великий ризик або неможливість досягнення

Також присутні додаткові позначки:

  • (skip) - вивчення аспекту було пропущено через занадто велику складність вивчення або зовнішні блокери, в тому числі від інших requirements

  • (not investigated) - вивчення аспекту не було визначено як важливе на даному етапі

Окрім того, в таблиці використовуються такі скорочення:

  • FTL - Freemarker Template Language

  • TML - Thymeleaf

Рішення Quill (+ react-quill) Draft.js TinyMCE (+ tinymce-react) CKEditor (+ ckeditor5-react) Slate (+ slate-react)

Загальна інформація

Ліцензія

BSD-3-Clause + MIT

MIT

MIT

GPL-2.0-or-later

MIT

Завантажень

868k+/329k+

795k+

302k+/136k+

177k+/72k+

332k+/263k+

Підтримка TypeScript

DT + TS

DT

TS

-

TS

Issues (Open/Closed)

1143/1891 + 229/419

773/970

944/4710 + 11/213

2440/7681 + 48/201

487/2355

PRs (Open/Closed)

89/450 + 13/141

166/1192

15/2099 + 0/81

41/1657 + 0/61

21/2057

Підтримка пакету

Остання стабільна версія 1.3.7 - три роки тому; готується реліз 2.х версії

Актуальна версія 0.11.7 - два роки тому

Останні оновлення - протягом попередніх тижнів

Останні оновлення - протягом попередніх тижнів

Досі в бета-режимі; часті зміни, відсутність стабільної версії

Складність інтеграції

S

L

M

L

L

Коментарі щодо складності інтеграції

Є невеликі нюанси із налаштуваннями додаткового функціонала

Потребує створення навіть найпростішого тулбара та операцій "з нуля"

Відносно легко, але потребує або API-ключ для хмарного використання, або додаткових налаштувань для бандлінгу, або копіювання статичних файлів

Базова інтеграція - нескладно, розширення функціоналу - складно

Майже потребує створення тулбару, форматів та серіалізації "з нуля"

Functional Requirements

Можливість завантаження зображень в inlined формі

S

XL

S

(skip)

L

Можливість використання зображень за URL лінками

M

XL

S

S

L

Можливість використання чітко визначених наборів стилів для формування та перегляду шаблонів

M

L

M

L

L

Використання чітко визначених css класів стилів в кожному наборі стилів задля підтримки темізації.

S

L

M

XL

L

Можливість налаштування кнопок для кодів шаблонізатора

S

(skip)

S

(skip)

(skip)

Можливість окремої стилізації для вставки значень шаблонізатора (включаючи репорт)

S

(skip)

S

(skip)

(skip)

Підсвічення вставок шаблонізатора при редагуванні (to be discussed)

(skip)

(skip)

S

(skip)

(skip)

Можливість вибору ключа значення шаблонізатора (назви змінної шаблонізатора) прі вставці значення

M

(skip)

M

(skip)

(skip)

Шаблонізація ітерованих даних

L

XL

M

(skip)

L

Лінки: href повинен підтримувати темплітизацію та підстановку значень змінних шаблонізатора

S

(skip)

S

(skip)

(skip)

Лінки: mailto посилання

S

(skip)

S

(skip)

(skip)

Таблиці: colgroup з можливістю коригування ширини колонок у відсотках

XL (M для 2.х.х)

(skip)

M

N/A

(skip)

Таблиці: товщина границь включно з нульовою

XL (M для 2.х.х)

(skip)

S

M

(skip)

Таблиці: alignment всередині комірок

XL (M для 2.х.х)

(skip)

S

M

(skip)

Таблиці: merge cells

XL (M для 2.х.х)

(skip)

S

S

(skip)

Таблиці: FTL-теги для умов та циклів

XL

XL

XL

XL

XL

Таблиці: TML-атрибути для умов та циклів

(skip)

(skip)

M

(skip)

(skip)

Два режими для редагування шаблону: WYSIWYG та вихідного коду, та синхронізація обох варіантів

S

M

S

S

M

Історія контенту (Undo/Redo)

M

(skip)

S

S

M

Non-functional Requirements

Доступність форматів "з коробки"

M

L

S

S

L

Централізація контенту (включно із зображеннями)

M

(skip)

S

M

(skip)

Шаблонізація для репортів

M

XL

M

L

L

Шаблонізація для email-листів

Додаткові класи для комірок таблиць

(skip)

(skip)

S

(skip)

(skip)

FTL: Створення кастомних тегів для умов та циклів

(skip)

(skip)

S

L

M

FTL: Створення кастомних тегів для умов та циклів у таблицях

XL

XL

XL

XL

XL

FTL: Окреме оформлення кастомних тегів у редакторі

S

(skip)

S

(skip)

(skip)

FTL: Додатковий інтерактивний функціонал кастомних тегів у редакторі

(not investigated)

(not investigated)

(not investigated)

(not investigated)

(not investigated)

TML: Збереження кастомних атрибутів для умов та циклів

M

(skip)

S

L

M

TML: Збереження кастомних атрибутів для умов та циклів у таблицях

(skip)

(skip)

M

(skip)

(skip)

TML: Окреме оформлення тегів з кастомними атрибутами у редакторі

(skip)

(skip)

S

(skip)

(skip)

TML: Додатковий інтерактивний функціонал тегів з кастомними атрибутами у редакторі

(not investigated)

(not investigated)

(not investigated)

(not investigated)

(not investigated)

Технічні нотатки

Тулбар "з коробки"

Присутній, кастомізується перелік та порядок кнопок та форматів

Відсутній, створюється з нуля

Присутній; багато функціоналу у вигляді вбудованих плагінів

Присутній; багато функціоналу у вигляді плагінів

Відсутній, створюється з нуля

Кастомізація зовнішнього вигляду тулбару

дві вбудовані теми (звичайний тулбар та тулбар-тултіп); додаткові кнопки - через псевдоелементи

повністю кастомний тулбар із кастомними стилями

можливість налаштування кількох тулбарів та кастомних кнопок

повністю кастомний тулбар із кастомними стилями

Кастомізація тулбару - створення кнопок

Самі кнопки - легко; операції з ними - мають певні нюанси для операцій оформлення елементів

Можливо, кнопки "ламаються" при синхронізації з іншим текстовим полем

Легко

Лише через створення додаткових плагінів

Можливо

Автоматичне форматування вмісту

+

+

+

+

+

Формати за замовчанням

Вбудований набір основних необхідних форматів

Вбудовані утиліти для створення форматів

Широкий набір форматів у рамках вбудованих плагінів

Широкий набір форматів у рамках зовнішніх плагінів

Гнучке створення форматів власноруч

Зображення (по URL)

Вручну, при вставленні за замовчанням

?

Вручну, при вставленні за замовчанням

Вручну, при вставленні за замовчанням

Зображення (base64)

За замовчанням при завантаженні з диску

?

Вбудований плагін для завантаження з диску

Зображення (upload на бекенд)

(not investigated), але існують зовнішні приклади

(not investigated)

(not investigated)

(not investigated)

(not investigated)

Зображення (вставити)

З іншого сайту - URL

З іншого сайту - не працює

З іншого сайту - URL

З іншого сайту - URL

Зображення (завантаження з диску)

За замовчанням - в base64

?

Вбудований плагін для завантаження з диску, base64

За замовчанням - нема дії, попередження про відсутність адаптера завантаження

Використання зовнішніх стилів для контенту

Легко, за іменами класів з підключених стилів, є певні обмеження по префіксах імен класів

Середня складність, необхідно задавати CSS як рядковий проп редактора

Використання inline-стилів для контенту

Легко, із використанням наперед визначених форматів та можливих значень

Легко, із використанням наперед визначених форматів та можливих значень

Використання шорт-кодів FTL

Легко за допомогою кастомних кнопок тулбару

Легко у разі заміни на кастомні теги

Прогнозовано легко за рахунок внутрішнього довільного формату даних

Використання атрибутів TML

Прогнозовано легко

Відносно легко

Прогнозовано легко за рахунок внутрішнього довільного формату даних

Можливість синхронізації вмісту з окремим текстовим полем для редагування вихідного коду

Тільки з десинхронізацією оновлення

Тільки з десинхронізацією оновлення; ламає функціонал операції форматування

Тільки з десинхронізацією оновлення; також є вбудований плагін із модалкою із власним десинхронізованим полем

Тільки з десинхронізацією оновлення; наче є плагін із модалкою, але не протестовано

Тільки з десинхронізацією оновлення

Синхронізація змін між режимами перегляду

Перегляд - в живому режимі, редагування - з десинхронізацією оновлення

Перегляд - в живому режимі, редагування - з десинхронізацією оновлення

Перегляд - в живому режимі, редагування - з десинхронізацією оновлення

Перегляд - в живому режимі, редагування - з десинхронізацією оновлення

Використання таблиць у контенті

Плагіни лише для 2.0.0-dev.3 та вище; для першої версії - нема

-

Вбудований плагін для управління таблицями; можна редагувати ширину таблиці та колонок, ховати границі, редагувати вирівнювання в комірках; усі стилі - інлайнові

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

Можливість імплементації шаблону репорту

Можливість імплементації email-шаблону

Експорт HTML

З коробки

З використанням зовнішньої бібліотеки

З коробки

З коробки

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

Інші формати експорту

-

Markdown - з використанням зовнішньої бібліотеки

Текстовий

-

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

Примітки

Зберігає контент у власному внутрішньому форматі, з якого та в який треба окремо конвертувати; операції залежні від фокуса елементу редактора, котрий конфліктує з іншими елементами форми

За замовчанням підтягується із зовнішньої хмари та потребує API-ключ; є можливість натомість бандлити

Відсутній TypeScript; окремі танці з бубном при управлінні залежностями і плагінами; все це робить підтримку коду досить складною; нові кнопки можна додавати лише через самописні плагіни

Still Beta; документація часто застаріла через нестабільність версій; зберігає контент у власному внутрішньому форматі; певні танці з бубном для TypeScript

Рішення за результатами аналізу

Рекомендовано використовувати TinyMCE у якості WYSIWYG-редактора з урахуванням відповідності вимогам, оцінкою ризиків імплементації та зручністю використання імплементованих демонстраційних рішень.

Підтримка темування та стилізації

Розглянуті рішення, в тому числі досліджувались на предмет можливості використання разом із зовнішніми таблицями стилів (у форматі CSS) для контенту як і у режимі редагування, так і у режимі попереднього перегляду. Внаслідок використання заздалегідь визначених CSS-класів з’являється можливість легкого редагування стилів та/або заміни таблиць стилів на аналогічні для інших тем без потреби внесення будь-яких змін у існуючий контент.

Усі розглянуті рішення так чи інакше або підтримують таку можливість, або виглядають як такі, що підтримують її. Так само розглянуті редактори переважно підтримують можливість стилізації елементів у режимі редагування саме із використанням CSS-класів замість інлайнових стилів.

Наполегливо рекомендується дотримуватись саме цього підходу та всіляко уникати використання інлайнових стилів через ризик неочікуваних змін дизайну в майбутньому та уникнення потреби редагувати існуючий контент у випадку зміни дизайну або появи нових тем контенту.
Також варто зазначити, що використання спеціальних класів та/або атрибутів у елементах створеного контенту дозволяє за потреби робити додаткові візуальні позначення для таких елементів у режимі редагування, а також додавати додатковий інтерактивний функціонал для редагування/перегляду цих елементів засобами JavaScript під час редагування/попереднього перегляду.

Підтримка локалізації

TinyMCE підтримує набір різних мов для елементів інтерфейсу "з коробки", включно з Українською. За потреби під час налаштування редактора є можливість вказати посилання на довільний набір перекладів елементів інтерфейсу, в тому числі для додатково реалізованих елементів управління, що дозволить створити локалізацію навіть для власних кнопок тощо.

Інтерфейс веб-редактора

Основний екран редактора під час формування витягу

wysiwyg editor report

Основний екран редактора під час формування витягу у режимі візуального перегляду блоків

wysiwyg editor report visualblocks

Управління директивами шаблонізатора

Ітерований контент за замовчанням виглядає так само як і звичайний контент, але у режимі перегляду блоків замість позначення лише типу блока також позначається і відповідна директива шаблонізатора (у лівому верхньому куті блоку).

Для перегляду конкретної формули, за котрою ітерується елемент, можна виділити його та натиснути кнопку відповідної директиви (як от кнопка "Loop"/"Цикл"), після чого у спливаючому вікні будуть доступними перегляд та редагування формули.

wysiwyg editor report edit loop

Для редагування директив для ітерованого та умовного контенту у таблицях використовується спеціальна кнопка "Manage Table" з відповідним спливаючим вікном, оскільки нема змоги коректно виділити окремий рядок або таблицю для визначення директив. Натомість для редагування директив у рядку та/або таблиці треба виділити будь-яку комірку усередині відповідного рядка/таблиці та натиснути відповідну кнопку, після чого обрати відповідну вкладку.

wysiwyg editor report table manage

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

wysiwyg editor report preview

Основний екран редактора під час формування електронного листа

wysiwyg editor email 001
wysiwyg editor email 002

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

wysiwyg preview email 001

Перегляд сформованого та надісланого листа у різних поштових клієнтах

Outlook (web)

wysiwyg preview email client outlook

Outlook (desktop, Windows)

wysiwyg preview email client outlook desktop

Gmail (web)

wysiwyg preview email client gmail

Моделювання email-листів у режимі WYSIWYG

Розділ у процесі доповнення

Цей розділ містить додатковий опис ризиків та пересторог, що стосуються email-шаблонів та пропозиції щодо розв’язання цих задач.

Вставлення зображень

У разі, якщо вставляти зображення за посиланням, деякі поштові клієнти можуть або зовсім не відображати їх, або ж відображати тільки після натиснення відповідної кнопки на кшталт "Показати заблокований вміст" (видно на наступному скріншоті).

wysiwyg preview email client outlook blocked

Існує кілька теоретичних способів вирішення цієї проблеми.

По-перше, зображення має бути розміщеним на тому ж домені, з якого відправляється лист, а при відправці налаштування мають бути налаштовані додаткові механізми підписання листа як от SPF-записи, DKIM-аутентифікація тощо.

З іншого боку можна додавати зображення у якості вкладення до листа та у тілі листа посилатись саме на ідентифікатор вкладення. Втім, за такого способу ми матимемо побічний ефект у вигляді наявності зайвого вкладення.

Також можна було б розглянути вставлення контенту зображень у якості інлайнового base64 всередині відповідного тегу, але, на жаль, цей спосіб також підтримується не всіма поштовими клієнтами. Наприклад, Gmail просто "вирізає" такі зображення.

Стилізація елементів

Часто поштові клієнти мають досить різні стандарти щодо підтримки тих чи інших елементів стилізації (як от відступи, кольори фону, фіксовані розміри елементів тощо). Ці стандарти не змінювались на протязі довгого періоду часу через питання зворотної сумісності зі старими email-клієнтами. Через це деякі клієнти можуть некоректно відображати ті чи інші елементи (як от "підвал" листа на прикладі з Outlook на Windows). Тому будь-яке впровадження нового формату листа потребує ретельної перевірки того, як відображається цей лист у широкій множині різних поштових клієнтів на різних платформах.

Також задля уникнення проблем із відступами та розмірами елементів подекуди використовується підхід "табличної верстки", за якої замість звичайних блоків використовуються таблиці з нульовими границями, вкладені у інші таблиці (довільний рівень вкладеності). Втім, використання WYSIWYG-редактора не передбачає роботи із вкладеними однотипними блоками та має обмежену підтримку оформлення вкладених таблиць, тому необхідно бути уважними під час редагування та/або створення email-шаблонів та виконувати усі дії з редагування пильно, бо завжди є ризик однією випадковою зміною "зламати" увесь шаблон.