Холодным Апрельским днем когда на Урале еще не растаял снег. Смеркалось. Я игрался с микро-шаблонами. К примеру: ejohn.org/blog/javascript-micro-templating/ Они все были сверхпроизводительны на пcевдо тестах, но в тоже время в них отсутствовал хоть какой либо более или менее серьезный функционал.
Последней каплей стало то что я пропустил js1k. One thing led to another. И в голову мне пришла интересная идея. Почему бы максимально не использовать возможности JS? Использовать синтаксис JS в шаблоне ( что позволит с помощью JS движка парсить шаблоны ) и использовать все возможности JS.
И получился шаблонный движок с довольно простым синтаксисом:
[TAG] raw( data: String ) | variable [TAG] [TAG].b [TAG].e [TAG] raw( data: String )
Что выглядит приблизительно так:
function _template() {
div.b;
span.context.value.span;
span.raw(11).span;
div.e;
hr;
raw('plain text')
}
div.b -> открывающийся тэг -> <div> div.e -> закрывающийся тэг -> </div> div.context.value.div -> <div>{{ context.value }}</div> hr -> самозакрывающийся тэг -> <hr/>
Получается своего рода DSL.
И какого размера код?
30 строчек кода :) Я уж не говорю про минифицированную версию.
Пример?
// Данные - на самом деле в шаблон можно передать
// любой JS обьект ( включая примитивы )
var data = [
{ name: 'STAN' },
{ name: 'Ai_boy' },
{ name: 'IceFrog' }
];
// Главный шаблон
function _template(){
// Через [ ] можно передать атрибуты нашему XML тегу
h1['class="head"'].raw('List of names').h1;
for (var i = 0; i < context.length; i++) {
// вызываем подшаблон
partial(_item, context[i]);
}
}
// Partial - подшаблон
function _item(){
b[args({style: 'color: blue', class: 'test'})].raw("Name:").b;
div.context.name.div;
hr;
}
// Написание кастомных helper функций никогда
// небыло настолько простым - просто пишем js
function args(obj){
var result = '';
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
result += key + '="' + obj[key] + '" ';
}
}
return result;
}
document.body.innerHTML = STAN.run(STAN.compile(_template), data);
Как начать?
Можно зайти на сайт и поиграться в Sandbox
aiboy.github.io/STAN/sandbox.html
Либо зайти на GitHub страницу и следовать инструкции в README.md
github.com/aiboy/STAN
(использовать шаблонизатор можно как в браузере так и в Node.js )
В чем плюс?
Главных приемущества ровно четыре:
1) Полная поддержка JS синтаксиса и всех его возможностей ( CoffeeScript, ClosureScript, TypeScript… ect )
2) Доступ к DOM в момент рендеринга шаблона.
3) Полная поддержка всех JS библиотек внутри шаблона ( lodash, underscore, jquery… ect )
4) Поддержка шаблонов в любом текстовом редакторе — ибо они на самом деле представляют из себя чистый JS синтаксис
А скорость?
Скорость «скомпилированного» шаблона ( который потом вручную или автоматически превращен в обычный js файл ) приблизительно равна скорости JavaScript :) Что весьма и весьма не плохо. Если динамически компилировать шаблоны то скорости увы не такие большие.
Почему не Zen Coding?
Потому что Zen Coding не возможно выразить в рамках JS синтаксиса — тоесть Zen Coding — не может быть валидным JS.
Это шутка?
Несмотря на безумность/глупость ( нужное подчеркнуть ) идеи. Все весьма и весьма серьезно. Проект будет развиваться. Обрастать тестами, более правильным синтаксисом и многими другими плюшками. Заходите на GitHub страничку — оставляйте ваши пожелания, найденные баги и все прочее.
PS: На самом деле я немного кревлю душой когда пишу что данный шаблонизатор состоит всего из 30 строк. Если честно отформатировать код то получится строк 40-50. Но для меня это больше психологический барьер которого я стараюсь придерживаться.
PPS: буду рад любым замечаниям по поводу «корректности и грамотности заметки» ( но будет лучше если все это будет написанно в личку )
Автор: Ai_boy