BEML — HTML препроцессор для BEM

Я начинаю потихоньку понимать выражение «БЭМ головного мозга», ну а что поделать, больного уже не спасти. На этот раз в голове моей родилась мысль облегчить написание БЭМ разметки путем небольшого расширения HTML синтаксиса (до этого я все эти длиннющие классы руками писал, ога). Название BEMHTML уже несправедливо занято ребятами из Яндекса, поэтому пусть будет BEML.

Цели

  1. Низкий порог вхождения — HTML синтаксис, без всяких трансляций одного языка в другой.
  2. Портабельность — инструмент должен легко портироваться на разные языки.
  3. Работа совместно с другими шаблонизаторами, а не вместо них.
  4. Простота использования — можно быстро заюзать где угодно.

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

К тому-же, при использовании BEMHTML есть одна неприятность — необходимо разворачивать Node.js в бэкенде для рендеринга шаблонов, ну или на худой конец как-то цеплять JS движок к PHP и Python c помощью какого-нибудь костыля вроде V8JS или PyV8. Можно конечно пойти и другим путем, разобрав уже отрендеренный шаблон HTML на кусочки, но это совсем уж изврат.

Хорошо-бы сделать препроцессор на JS и к нему таск для Grunt, дабы нормально написать прототипы, а затем написать нативный порт препроцессора на PHP и свободно юзать те-же шаблоны уже в бэкенде, если взлетит, конечно.

Принцип работы

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

Схема работы примерно следующая: мы передаем шаблон в абсолютно любой шаблонизатор, который наполняет HTML данными и выполняет все остальные действия, присущие шаблонизатору, а потом отдает его не клиенту, как обычно, а по цепочке у же в постпроцессор, который займется раскрытием синтаксических конструкций БЭМа в нормальный HTML, а только затем разметка уходит клиенту.

Но быстрее да и просто предпочтительнее сначала отправить шаблон в препроцессор, который транслирует БЭМ атрибуты в HTML, его закэшировать, а потом отдавать кэшированную копию в ваш любимый шаблонизатор. Синтаксические конструкции самого шаблонизатора при этом, понятное дело, не пострадают.

Синтаксис

Заморачиваться особо негде, все расширение сводится к добавлению четырех атрибутов: block, elem, mod и mix. За что каждый из них отвечает, думаю, объяснять не надо. Для множественных значений так же используется облегченный диалект JSON, без кавычек и с возможностью отбросить фигурные скобки. В итоге получили приблуду, которая разворачивает такой код:

<div block="b-animals">
  <div elem="cat" mod="size:big, color:red"></div>
</div>

в такой:

<div class="b-animals">
  <div class="b-animals__cat b-animals__cat_size_big b-animals__cat_color_red"></div>
</div>

Читать заметно удобнее, день прожит не зря.

Как попробовать

$ npm install beml
var beml = require('beml');
var template = '<div block="b-block" mod="size:big"></div>';

var output = beml.process(template);
console.log(output);

Полный обзор синтаксиса есть в README на GitHub.