STAN - найкоротший шаблонний движок

    image
 
Холодним Квітневим днем ​​коли на Уралі ще не розтанув сніг. Сутеніло. Я грався з мікро-шаблонами. Наприклад: 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 синтаксис
 
 А швидкість?
 jsperf.com / stan-speed-test
 image
 
Швидкість «скомпільованого» шаблону (який потім вручну або автоматично перетворений на звичайний js файл) приблизно дорівнює швидкості JavaScript :) Що вельми і вельми не погано. Якщо динамічно компілювати шаблони то швидкості жаль не такі великі.
 
 Чому не Zen Coding?
Тому що Zen Coding неможливо виразити в рамках JS синтаксису — тоесть Zen Coding — не може бути валідним JS.
 
 Це жарт?
Незважаючи на шалену / дурість (потрібне підкреслити) ідеї. Всі вельми і вельми серйозно. Проект буде розвиватися. Обростати тестами, більш правильним синтаксисом і багатьма іншими пляшками. Заходьте на GitHub сторінку — залишайте ваші побажання, знайдені баги і все інше.
 
 PS: Насправді я трохи кревлю душею коли пишу що даний шаблонизатор складається всього з 30 рядків. Якщо чесно відформатувати код то вийде рядків 40-50. Але для мене це більше психологічний бар'єр якого я намагаюся дотримуватися.
 
PPS: буду радий будь-яких зауважень з приводу «коректності і грамотності нотатки» (але буде краще якщо все це буде написано в личку)

  

    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.