nuckty
EN
Все разделы →

Двухпроходный рендеринг

Решение

Разделить применение шаблонов и сериализацию HTML. Публичная функция render по умолчанию возвращает HTML; режим output: 'bemjson' возвращает готовое дерево BEMJSON.

Внутри движка renderToBemJson применяет все структурные режимы и режимы отображения, затем renderToHtml сериализует результат и выполняет минимизацию HTML. Эти внутренние функции не экспортируются отдельно из корня пакета.

Контекст

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

Альтернативы

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

Отдельные языки шаблонов для данных и HTML. Они разделяют обязанности, но требуют двух правил написания шаблонов. nuckty сохраняет единый синтаксис деклараций nu.

Аргумент

Первый проход вычисляет все режимы шаблонов, включая tag, attrs, content, replace и wrap. Второй не применяет шаблонов. Результат каждого этапа можно исследовать и проверять отдельно.

Автор описывает блок в одном файле .nu.ts. Движок не позволяет управляющему шаблону повторно применяться к тому же узлу; произвольная рекурсия в пользовательском коде всё ещё возможна.

Последствия

Для просмотра готового дерева используйте render(tree, { templates, output: 'bemjson' }), для фрагмента HTML — render(tree, { templates }). Параметр document: true добавляет doctype и окончание документа.

В разработке и в продакшене действует один режим рендеринга. Второй проход не гарантирует допустимость произвольного HTML: валидация остаётся отдельной командой.