...

воскресенье, 8 июня 2014 г.

[recovery mode] STAN — самый короткий шаблонный движок

image

Холодным Апрельским днем когда на Урале еще не растаял снег. Смеркалось. Я игрался с микро-шаблонами. К примеру: http://ift.tt/X0c9R7 Они все были сверхпроизводительны на п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

http://ift.tt/1kV6Cqd

Либо зайти на GitHub страницу и следовать инструкции в README.md

http://ift.tt/1kV6Dub

(использовать шаблонизатор можно как в браузере так и в Node.js )


В чем плюс?




Главных приемущества ровно четыре:

1) Полная поддержка JS синтаксиса и всех его возможностей ( CoffeeScript, ClosureScript, TypeScript… ect )


2) Доступ к DOM в момент рендеринга шаблона.


3) Полная поддержка всех JS библиотек внутри шаблона ( lodash, underscore, jquery… ect )


4) Поддержка шаблонов в любом текстовом редакторе — ибо они на самом деле представляют из себя чистый JS синтаксис


А скорость?




http://ift.tt/UlzL91

image

Скорость «скомпилированного» шаблона ( который потом вручную или автоматически превращен в обычный js файл ) приблизительно равна скорости JavaScript :) Что весьма и весьма не плохо. Если динамически компилировать шаблоны то скорости увы не такие большие.


Почему не Zen Coding?




Потому что Zen Coding не возможно выразить в рамках JS синтаксиса — тоесть Zen Coding — не может быть валидным JS.

Это шутка?




Несмотря на безумность/глупость ( нужное подчеркнуть ) идеи. Все весьма и весьма серьезно. Проект будет развиваться. Обрастать тестами, более правильным синтаксисом и многими другими плюшками. Заходите на GitHub страничку — оставляйте ваши пожелания, найденные баги и все прочее.

PS: На самом деле я немного кревлю душой когда пишу что данный шаблонизатор состоит всего из 30 строк. Если честно отформатировать код то получится строк 40-50. Но для меня это больше психологический барьер которого я стараюсь придерживаться.


PPS: буду рад любым замечаниям по поводу «корректности и грамотности заметки» ( но будет лучше если все это будет написанно в личку )


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий