SlideShare a Scribd company logo
Шаблонизация
Как
дедушка
завещал
Алексей Ярошевич
@zxqfox
@yaroshevich
qfox@ya.ru



План вещания
— Немножко теории
— «Родословная» шаблонизаторов
— Веления и предписания
— Взгляд изнутри
— Идеальный шаблонизатор
2
Немножко теории
Шаблоны — схема преобразования данных из одного формата в другой.
Функция (отображение, оператор, преобразование) — связь между
элементами множеств.““
4
function processor(template, data) { };
var fn = processor.bind(undefined, template);
var fn = processor.compile(template);
fn(data) processor(template, data); true
01.
02.
03.
04.
5
«Родословная»
шаблонизаторов
и их полезности
«Родословная» шаблонизаторов
— Текстовые препроцессоры (и препроцессоры для кода; C 1972)
— Скриптовые языки (e.g. SmallTalk 1969-1980; Perl 1988; Lua 1993)
— Веб-серверы и CGI (CERN httpd 1990; NCSA HTTPd 1993; Apache 1995)
— Простейшие (PHP/FI 1995; TT2 1996)
— Классические (XSLT 1999; WebMacro/Velocity 1999; Smarty 2000; etc.)
Smarty — шаблонизатор, написанный на бывшем шаблонизаторе.
7
Полезности
— Декомпозиция и DRY — разделение кода на куски;
— отделение view от логики (MVC? не, не слышал);
— простота и красота — синтаксический «сахар»;
— «царапки» — защита от дурака;
— хелперы — вспомогательные методы для вывода.
Как итог: разделение ответственности и новая профессия.
8
Веления и предписания
Веления или императивный подход
— Представители: Assembler, C, JavaScript;
— Процесс описывается инструкциями;
— интенсивно используется присваивание;
— И исполняется последовательно.
class Employee extends Person { Declaration, right?
constructor(name) {
super.constuctor(name);
}
}
01.
02.
03.
04.
05.
10
Пример HTML-кода
<h2 class="caption">Heading</h2>
<ul class="people">
<li class="people__person">John</li>
<li class="people__person">Malkovich</li>
<li class="people__person last">Doe</li>
</ul>
HTML— формат данных + декларативный язык.
01.
02.
03.
04.
05.
06.
07.
08.
09.
11
Шаблон на PHP
<h2 class="caption"><?= $caption ?></h2>
<ul class="people">
<? foreach ($people as $i $person): ?>
<? $isLast = ($i < count($people) - 1); ?>
<li class="people__person <?= $isLast? 'last' : '' ?>">
<?= $person ?>
</li>
<? endforeach ?>
</ul>
//bit.ly/tplcmp
01.
02.
03.
04.
05.
06.
07.
08.
09.
12
Шаблон Smarty
<h2 class="caption">{$caption}</h2>
<ul class="people">
{foreach from=$people item=person name=people}
{var isLast=$smarty.foreach.people.last}
<li class="people__person {if $isLast}last{/if}">
{$person}
</li>
{/foreach}
</ul>
//bit.ly/tplcmp
01.
02.
03.
04.
05.
06.
07.
08.
09.
13
Шаблон EJS
<h2 class="caption"><%= caption %></h2>
<ul class="people">
<% for (var i = 0; i < people.length; i ) { %>
<% var isLast = i < people.length - 1; %>
<li class="people__person <%= isLast? 'last' : '' %>">
<%= people[i] %>
</li>
<% } %>
</ul>
//bit.ly/tplcmp
01.
02.
03.
04.
05.
06.
07.
08.
09.
14
Шаблон Mustache
<h2 class="caption"><{{caption}}</h2>
<ul class="people">
{{#people}}
<li class="people__person {{^last}}last{{/last}}">
{{.}}
</li>
{{/people}}
</ul>
//bit.ly/tplcmp
01.
02.
03.
04.
05.
06.
07.
08.
09.
15
Шаблоны для Angular
<h2 class="caption">{{caption}}</h2>
<ul class="people"
ng-repeat="person in people">
<li class="people__person {{$last? 'last' : ''}}">
{{person}}
</li>
</ul>
01.
02.
03.
04.
05.
06.
07.
08.
09.
16
Шаблоны на React JSX
<h2 className="caption">{this.props.caption}</h2>
<ul className="people">
{this.props.people.map(function(person, i, people) {
var lastCls = i people.length - 1 ? 'last' : '';
return <li className={"people__person " + lastCls}>
{person}
</li>;
})}
</ul>
01.
02.
03.
04.
05.
06.
07.
08.
09.
17
Псевдокод
вывести '<h2 class="caption">';
вывести caption;
вывести '</h2>';
вывести '<ul class="people">';
перебор по person из people;
вывести '<li class="people__person ';
вывести 'last' если последний;
вывести '">';
вывести person;
вывести '</li>';
вывести '</ul>';
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
18
Проблемы императивного подхода
— Несоразмерный рост сложности модели вычислений;
— предсказать результат работы — крайне сложно;
— большинство таких шаблонизаторов — синтаксический «сахар».
Ой-ой.
19
Предписания или декларативный подход
— Представители: HTML, CSS, SQL, XSLT;
— описывают желаемые результаты, а не процесс их достижения;
— часто детерминированность и функциональная чистота;
— порядок инструкций в блоке не важен.
XML + XSLT— наше все?
Структурированный JSON + Plates, Yate, BEMXJST, BH — тоже вариант.
20
Пример HTML-кода еще раз
<h2 class="caption">Heading</h2>
<ul class="people">
<li class="people__person">John</li>
<li class="people__person">Malkovich</li>
<li class="people__person last">Doe</li>
</ul>
01.
02.
03.
04.
05.
06.
07.
08.
09.
21
XSLT-шаблон
<xsl:template match="caption">
<h2 class="caption"><xsl:value-of select="." </h2>
</xsl:template>
<xsl:template match="people">
<ul class="people"><xsl:apply-templates select="person" </ul>
</xsl:template>
<xsl:template match="person">
<li class="people__person"><xsl:value-of select="." </li>
</xsl:template>
<xsl:template match="person[position() = last()]">
<li class="people__person last"><xsl:value-of select="." </li>
</xsl:template>
Nota bene: Опущена стандартная обертка XSLT
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
22
Данные в XML
<?xml version="1.0"?>
<data>
<caption>Cap</caption>
<people>
<person>John</person>
<person>Malkovich</person>
<person>Doe</person>
</people>
</data>
01.
02.
03.
04.
05.
06.
07.
08.
09.
23
Шаблоны на BH
bh.match('caption', function (ctx) {
ctx.tag('h2');
});
bh.match('people', function (ctx) {
ctx.tag('ul');
});
bh.match('people__person', function (ctx) {
ctx.tag('li');
if(ctx.isLast()) ctx.cls('last'); Императив!
});
Декларативненько — когда порядок роли не играет.
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
24
И данные в формате BEMJSON
[
{ block: 'caption', content: 'Heading' },
{ block: 'people', content: [
{ elem: 'person', content : 'John' },
{ elem: 'person', content : 'Malkovich' },
{ elem: 'person', content : 'Doe' }
] }
]
01.
02.
03.
04.
05.
06.
07.
08.
25
Шаблон на выдуманном CHS
caption {
tag: h2;
}
people {
tag: ul;
}
people__person {
tag: li;
}
people__person:last-child {
class: last;
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
26
Проблемки декларативного подхода?
— Входные данные нужно готовить;
— сносит голову — функциональщина близко;
— медленнее, при использовании в лоб.
27
Еще раз о различиях
Императив
— Последовательное исполнение
— Описывается процесс
— Циклы и условия
— Присваивание переменных
Декларатив
— Порядок не важен
— Описывается результат
— Цепочки вызовов примитивов
— Монады и гонады
Любая программа балансирует между императивом и декларативом.
28
Нюансы
Строковые vs DOM-шаблонизаторы
— Строковые на клиенте — медленно;
— DOM-шаблонизаторы на сервере — боль.
Хороший шаблонизатор должен быть многостаночником.
30
Предметная ориентация
Разделение классического подхода на 2 преобразования.
— Построение view-ориентированной структуры
(энтропия, грязные функции, получение данных из окружения);
— Преобразование в HTML-строку с разметкой сущностей;
— Преобразование в DOM-ноды на клиенте.
Компоненты — абстракция в различных технологиях над DOM.
31
32
Преобразование: исходник
{
pageTitle: 'Контакты',
people: [
{ id: 42, name: 'Иван Дорн',
email: 'ivan@dorn.me' },
{ id: 77, name: 'Пересвет Янсон',
email: 'peresvetik@ya.ru' }
]
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
33
Преобразование: view-json
{
type: 'page',
title: 'Контакты — Мой сайт',
children: [
{ type: 'heading', level: 2, children: 'Контакты' },
{ type: 'people', children: [
{ type: 'person', children: 'Дорн И.' },
{ type: 'person', children: 'Янсон П.' }
] }
]
}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
34
Преобразование: результат
<!doctype html>
<html>
<head><title>Контакты — Мой сайт</title></head>
<body>
<h2 class="heading">Контакты</h2>
<ul class="people">
<li class="person">Дорн И.</li>
<li class="person">Янсон П.</li>
</ul>
</body>
</html>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
35
Взгляд изнутри
Компиляция и среда выполнения
Компиляция — преобразование кода шаблонов в исполняемый код.
«Рантайм» — запускает код или предоставляет функционал.
— Статический анализ — проверяет, структуризует и ускоряет код;
— декларативный код — проще разбирается, шире маневр.
Императивность в деталях — допустима, но чувствуйте грань.
37
Энтропия и побочные-эффекты
Примеры: Date , Math.random , XHR.* , global.* .
— Медленнее;
— проблемы с отладкой (и тестами);
— нельзя параллелить;
— нельзя кешировать.
Непредсказуемы, что с них взять? В мусор!
38
Изоморфизм
Рендеринг одних шаблонов и на сервере, и на клиенте.
— 2 среды выполнения — для каждого окружения;
— 1 среда выполнения ( !), и компиляция;
— Компиляция вместе с «рантаймом» (жыр).
DOM-деревья, кеширование, «VirtualDOM»?
Несколько рендеров, чистые функции, персистентные хранилища.
39
Попахивает функциональщиной...
— Чистые функции (без энтропии);
— запоминание результатов (мемоизация);
— персистентные хранилища (immutable.js);
— новый уровень абстракции.
Может еще и параллелить? Камень зря простаивает. Temple?
40
Живой пример
41
Дерево компонентов React JSX
<SidebarComponent>
<Logo image="/images/logo.svg"
<Nav>
<Link url="/events.html">События</Link>
<Link url="/speakers.html">Люди</Link>
</Nav>
<SubscribeForm provider="mailchimp" id="ae74b08571"
</SidebarComponent>
Левая колонка moscowjs.ru
01.
02.
03.
04.
05.
06.
07.
08.
42
Дерево компонентов в формате BEMJSON
{ block: 'SidebarComponent', content: [
{ block: 'Logo', image: '/images/logo.svg' },
{ block: 'Nav', content: [
{ block: 'Link',
url: '/events.html', content: 'События' },
{ block: 'Link',
url: '/speakers.html', content: 'Люди' },
] },
{ block: 'SubscribeForm',
provider: 'mailchimp', id: 'ae74b08571' }
] }
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
43
Идеальный веб-шаблонизатор
— предметная ориентированность;
— чистота шаблонов («сахар»);
— модульность (частичная отрисовка);
— легкий и быстрый рантайм;
— чистота и независимость от внешней среды;
— инфраструктура и удобство разработки;
Nota bene: Скорость разработки VS масштабируемость VS поддержка.
44
Предметно-ориентированные кандидаты
— React JSX: императивный, JSX, VirtualDOM, строки и DOM;
— BH: более декларативный, JS, чистый, строки или BEMJSON;
— BEMHTML: еще более декларативный, свой/JS, чистый, строки;
— Basis: смешанный, HTML+, строки и DOM;
— Temple?
45
Тигр
Ссылки
— youtu.be/7fFggu1fZIs — Лекция «Абстракция и декомпозиция.
Декларативное программирование»
— bit.ly/tplveged — Лекция «Про шаблонизаторы вообще, и BEMHTML в
частности», Сергей Бережной
— youtu.be/b0EF0VTs9Dc — EN: Лекция «Monads and Gonads», Crockford
— bit.ly/tplcmp — Gist про сравнение шаблонизаторов
47
Вопросы?
Алексей Ярошевич, Dalee Digital Agency
@zxqfox
@yaroshevich
qfox@ya.ru
j.mp/ttmpl
Шаблонизация, как дедушка завещал



48

More Related Content

PDF
Лекция 4 Client-side
PDF
CSS глазами машин
PDF
Basis.js - Production Ready Framework
PDF
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
PDF
Basis.js - Production Ready SPA Framework
ODP
Семинар-практикум по Drupal
PDF
Noveo web intership html5, css, interface
Лекция 4 Client-side
CSS глазами машин
Basis.js - Production Ready Framework
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
Basis.js - Production Ready SPA Framework
Семинар-практикум по Drupal
Noveo web intership html5, css, interface

What's hot (13)

PDF
MongoDB@addconf
PDF
Лекция #7. Django ORM
PPT
Rose::DB
PDF
PDF
Михаил Трошев — CSS: Систематизация базовых знаний
PPTX
Web осень 2013 лекция 4
PPT
Web весна 2012 лекция 10
PDF
Как создать сайт
PPT
Web весна 2012 лекция 4
PPTX
мова Html
PDF
Павел Горобцов: Основы CSS
PDF
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
PPT
Web весна 2013 лекция 11
MongoDB@addconf
Лекция #7. Django ORM
Rose::DB
Михаил Трошев — CSS: Систематизация базовых знаний
Web осень 2013 лекция 4
Web весна 2012 лекция 10
Как создать сайт
Web весна 2012 лекция 4
мова Html
Павел Горобцов: Основы CSS
SECON'2014 - Павел Щеваев - Метаданные и автогенерация кода
Web весна 2013 лекция 11
Ad

Similar to Шаблонизация (20)

PDF
Сергей Бережной "Про шаблонизаторы вообще и BEMHTML в частности"
PDF
Мастер-класс наоборот: вы пишете БЭМ-проект, а мы подсказываем — Евгений Конс...
PDF
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
PDF
basis.js - почему я не бросил разрабатывать свой фреймворк
PDF
Рендеринг может больше: vue.js vs React, Андрей Солодовников
PDF
React со скоростью света: не совсем обычный серверный рендеринг
PDF
Олег Мохов: Модель Отображения. Браузеры
PDF
D2D Pizza JS Илья Беда "Куда мы все катимся?"
PDF
Сергей Бережной "Клиентский JavaScript в БЭМ-терминах: от блока до библиотеки"
PDF
C# Web. Занятие 16.
PPTX
I tmozg js_school
PDF
Vladimir Grinenko - "Dependencies in component web done right"
PDF
J query tutorial-for-beginners-1.0.2
PDF
J query шевчук
PPT
Web осень 2012 лекция 9
PDF
Jquery_tutorial_for-beginners
PDF
JavaScript Базовый. Занятие 11.
PDF
Изоморфный JavaScript — будущее уже здесь
PDF
Тимофей Перевезенцев. Кухня современных python шаблонизаторов
PDF
Сайт с нуля на полном стеке БЭМ-технологий
Сергей Бережной "Про шаблонизаторы вообще и BEMHTML в частности"
Мастер-класс наоборот: вы пишете БЭМ-проект, а мы подсказываем — Евгений Конс...
Владимир Гриненко "i-bem.js: JavaScript в БЭМ-терминах"
basis.js - почему я не бросил разрабатывать свой фреймворк
Рендеринг может больше: vue.js vs React, Андрей Солодовников
React со скоростью света: не совсем обычный серверный рендеринг
Олег Мохов: Модель Отображения. Браузеры
D2D Pizza JS Илья Беда "Куда мы все катимся?"
Сергей Бережной "Клиентский JavaScript в БЭМ-терминах: от блока до библиотеки"
C# Web. Занятие 16.
I tmozg js_school
Vladimir Grinenko - "Dependencies in component web done right"
J query tutorial-for-beginners-1.0.2
J query шевчук
Web осень 2012 лекция 9
Jquery_tutorial_for-beginners
JavaScript Базовый. Занятие 11.
Изоморфный JavaScript — будущее уже здесь
Тимофей Перевезенцев. Кухня современных python шаблонизаторов
Сайт с нуля на полном стеке БЭМ-технологий
Ad

More from DALEE digital agency (20)

PDF
Как сделать крутую презентацию
PDF
Scrum. Чем он может навредить агентству
PDF
Как мы улучшали сайт главного банка страны
PDF
Как мы улучшали сайт главного банка страны
PDF
Критерии оценки участников тендера
PDF
Агентство: инструкция по применению
PDF
Агентство: кто все эти люди?
PDF
Закупка digital-услуг. Постановка проблемы. Тендеры. Пример качественного брифа
PDF
Профессия "Менеджер проектов в digital"
PDF
Экономика 
 digital-агентства
PDF
Поддержка масштабного сайта усилиями агентств
PDF
Опыт реализации и поддержки больших проектов: координация команд, координация...
PDF
BEM на корпоративном веб-ресурсе — отказоустойчивость фронтенда
PDF
Как делать крутые слайды
PDF
All About Creative Concept
PDF
Сложный проект для "сложного" клиента
PDF
Критерии оценки креатива
PDF
Способы выбора эффективного агентства на digital-услуги
PDF
10 важных вещей digital-медиапланирования
PDF
Как думают закупщики?
Как сделать крутую презентацию
Scrum. Чем он может навредить агентству
Как мы улучшали сайт главного банка страны
Как мы улучшали сайт главного банка страны
Критерии оценки участников тендера
Агентство: инструкция по применению
Агентство: кто все эти люди?
Закупка digital-услуг. Постановка проблемы. Тендеры. Пример качественного брифа
Профессия "Менеджер проектов в digital"
Экономика 
 digital-агентства
Поддержка масштабного сайта усилиями агентств
Опыт реализации и поддержки больших проектов: координация команд, координация...
BEM на корпоративном веб-ресурсе — отказоустойчивость фронтенда
Как делать крутые слайды
All About Creative Concept
Сложный проект для "сложного" клиента
Критерии оценки креатива
Способы выбора эффективного агентства на digital-услуги
10 важных вещей digital-медиапланирования
Как думают закупщики?

Шаблонизация

  • 2. План вещания — Немножко теории — «Родословная» шаблонизаторов — Веления и предписания — Взгляд изнутри — Идеальный шаблонизатор 2
  • 4. Шаблоны — схема преобразования данных из одного формата в другой. Функция (отображение, оператор, преобразование) — связь между элементами множеств.““ 4
  • 5. function processor(template, data) { }; var fn = processor.bind(undefined, template); var fn = processor.compile(template); fn(data) processor(template, data); true 01. 02. 03. 04. 5
  • 7. «Родословная» шаблонизаторов — Текстовые препроцессоры (и препроцессоры для кода; C 1972) — Скриптовые языки (e.g. SmallTalk 1969-1980; Perl 1988; Lua 1993) — Веб-серверы и CGI (CERN httpd 1990; NCSA HTTPd 1993; Apache 1995) — Простейшие (PHP/FI 1995; TT2 1996) — Классические (XSLT 1999; WebMacro/Velocity 1999; Smarty 2000; etc.) Smarty — шаблонизатор, написанный на бывшем шаблонизаторе. 7
  • 8. Полезности — Декомпозиция и DRY — разделение кода на куски; — отделение view от логики (MVC? не, не слышал); — простота и красота — синтаксический «сахар»; — «царапки» — защита от дурака; — хелперы — вспомогательные методы для вывода. Как итог: разделение ответственности и новая профессия. 8
  • 10. Веления или императивный подход — Представители: Assembler, C, JavaScript; — Процесс описывается инструкциями; — интенсивно используется присваивание; — И исполняется последовательно. class Employee extends Person { Declaration, right? constructor(name) { super.constuctor(name); } } 01. 02. 03. 04. 05. 10
  • 11. Пример HTML-кода <h2 class="caption">Heading</h2> <ul class="people"> <li class="people__person">John</li> <li class="people__person">Malkovich</li> <li class="people__person last">Doe</li> </ul> HTML— формат данных + декларативный язык. 01. 02. 03. 04. 05. 06. 07. 08. 09. 11
  • 12. Шаблон на PHP <h2 class="caption"><?= $caption ?></h2> <ul class="people"> <? foreach ($people as $i $person): ?> <? $isLast = ($i < count($people) - 1); ?> <li class="people__person <?= $isLast? 'last' : '' ?>"> <?= $person ?> </li> <? endforeach ?> </ul> //bit.ly/tplcmp 01. 02. 03. 04. 05. 06. 07. 08. 09. 12
  • 13. Шаблон Smarty <h2 class="caption">{$caption}</h2> <ul class="people"> {foreach from=$people item=person name=people} {var isLast=$smarty.foreach.people.last} <li class="people__person {if $isLast}last{/if}"> {$person} </li> {/foreach} </ul> //bit.ly/tplcmp 01. 02. 03. 04. 05. 06. 07. 08. 09. 13
  • 14. Шаблон EJS <h2 class="caption"><%= caption %></h2> <ul class="people"> <% for (var i = 0; i < people.length; i ) { %> <% var isLast = i < people.length - 1; %> <li class="people__person <%= isLast? 'last' : '' %>"> <%= people[i] %> </li> <% } %> </ul> //bit.ly/tplcmp 01. 02. 03. 04. 05. 06. 07. 08. 09. 14
  • 15. Шаблон Mustache <h2 class="caption"><{{caption}}</h2> <ul class="people"> {{#people}} <li class="people__person {{^last}}last{{/last}}"> {{.}} </li> {{/people}} </ul> //bit.ly/tplcmp 01. 02. 03. 04. 05. 06. 07. 08. 09. 15
  • 16. Шаблоны для Angular <h2 class="caption">{{caption}}</h2> <ul class="people" ng-repeat="person in people"> <li class="people__person {{$last? 'last' : ''}}"> {{person}} </li> </ul> 01. 02. 03. 04. 05. 06. 07. 08. 09. 16
  • 17. Шаблоны на React JSX <h2 className="caption">{this.props.caption}</h2> <ul className="people"> {this.props.people.map(function(person, i, people) { var lastCls = i people.length - 1 ? 'last' : ''; return <li className={"people__person " + lastCls}> {person} </li>; })} </ul> 01. 02. 03. 04. 05. 06. 07. 08. 09. 17
  • 18. Псевдокод вывести '<h2 class="caption">'; вывести caption; вывести '</h2>'; вывести '<ul class="people">'; перебор по person из people; вывести '<li class="people__person '; вывести 'last' если последний; вывести '">'; вывести person; вывести '</li>'; вывести '</ul>'; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 18
  • 19. Проблемы императивного подхода — Несоразмерный рост сложности модели вычислений; — предсказать результат работы — крайне сложно; — большинство таких шаблонизаторов — синтаксический «сахар». Ой-ой. 19
  • 20. Предписания или декларативный подход — Представители: HTML, CSS, SQL, XSLT; — описывают желаемые результаты, а не процесс их достижения; — часто детерминированность и функциональная чистота; — порядок инструкций в блоке не важен. XML + XSLT— наше все? Структурированный JSON + Plates, Yate, BEMXJST, BH — тоже вариант. 20
  • 21. Пример HTML-кода еще раз <h2 class="caption">Heading</h2> <ul class="people"> <li class="people__person">John</li> <li class="people__person">Malkovich</li> <li class="people__person last">Doe</li> </ul> 01. 02. 03. 04. 05. 06. 07. 08. 09. 21
  • 22. XSLT-шаблон <xsl:template match="caption"> <h2 class="caption"><xsl:value-of select="." </h2> </xsl:template> <xsl:template match="people"> <ul class="people"><xsl:apply-templates select="person" </ul> </xsl:template> <xsl:template match="person"> <li class="people__person"><xsl:value-of select="." </li> </xsl:template> <xsl:template match="person[position() = last()]"> <li class="people__person last"><xsl:value-of select="." </li> </xsl:template> Nota bene: Опущена стандартная обертка XSLT 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 22
  • 23. Данные в XML <?xml version="1.0"?> <data> <caption>Cap</caption> <people> <person>John</person> <person>Malkovich</person> <person>Doe</person> </people> </data> 01. 02. 03. 04. 05. 06. 07. 08. 09. 23
  • 24. Шаблоны на BH bh.match('caption', function (ctx) { ctx.tag('h2'); }); bh.match('people', function (ctx) { ctx.tag('ul'); }); bh.match('people__person', function (ctx) { ctx.tag('li'); if(ctx.isLast()) ctx.cls('last'); Императив! }); Декларативненько — когда порядок роли не играет. 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 24
  • 25. И данные в формате BEMJSON [ { block: 'caption', content: 'Heading' }, { block: 'people', content: [ { elem: 'person', content : 'John' }, { elem: 'person', content : 'Malkovich' }, { elem: 'person', content : 'Doe' } ] } ] 01. 02. 03. 04. 05. 06. 07. 08. 25
  • 26. Шаблон на выдуманном CHS caption { tag: h2; } people { tag: ul; } people__person { tag: li; } people__person:last-child { class: last; } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 26
  • 27. Проблемки декларативного подхода? — Входные данные нужно готовить; — сносит голову — функциональщина близко; — медленнее, при использовании в лоб. 27
  • 28. Еще раз о различиях Императив — Последовательное исполнение — Описывается процесс — Циклы и условия — Присваивание переменных Декларатив — Порядок не важен — Описывается результат — Цепочки вызовов примитивов — Монады и гонады Любая программа балансирует между императивом и декларативом. 28
  • 30. Строковые vs DOM-шаблонизаторы — Строковые на клиенте — медленно; — DOM-шаблонизаторы на сервере — боль. Хороший шаблонизатор должен быть многостаночником. 30
  • 31. Предметная ориентация Разделение классического подхода на 2 преобразования. — Построение view-ориентированной структуры (энтропия, грязные функции, получение данных из окружения); — Преобразование в HTML-строку с разметкой сущностей; — Преобразование в DOM-ноды на клиенте. Компоненты — абстракция в различных технологиях над DOM. 31
  • 32. 32
  • 33. Преобразование: исходник { pageTitle: 'Контакты', people: [ { id: 42, name: 'Иван Дорн', email: 'ivan@dorn.me' }, { id: 77, name: 'Пересвет Янсон', email: 'peresvetik@ya.ru' } ] } 01. 02. 03. 04. 05. 06. 07. 08. 09. 33
  • 34. Преобразование: view-json { type: 'page', title: 'Контакты — Мой сайт', children: [ { type: 'heading', level: 2, children: 'Контакты' }, { type: 'people', children: [ { type: 'person', children: 'Дорн И.' }, { type: 'person', children: 'Янсон П.' } ] } ] } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 34
  • 35. Преобразование: результат <!doctype html> <html> <head><title>Контакты — Мой сайт</title></head> <body> <h2 class="heading">Контакты</h2> <ul class="people"> <li class="person">Дорн И.</li> <li class="person">Янсон П.</li> </ul> </body> </html> 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 35
  • 37. Компиляция и среда выполнения Компиляция — преобразование кода шаблонов в исполняемый код. «Рантайм» — запускает код или предоставляет функционал. — Статический анализ — проверяет, структуризует и ускоряет код; — декларативный код — проще разбирается, шире маневр. Императивность в деталях — допустима, но чувствуйте грань. 37
  • 38. Энтропия и побочные-эффекты Примеры: Date , Math.random , XHR.* , global.* . — Медленнее; — проблемы с отладкой (и тестами); — нельзя параллелить; — нельзя кешировать. Непредсказуемы, что с них взять? В мусор! 38
  • 39. Изоморфизм Рендеринг одних шаблонов и на сервере, и на клиенте. — 2 среды выполнения — для каждого окружения; — 1 среда выполнения ( !), и компиляция; — Компиляция вместе с «рантаймом» (жыр). DOM-деревья, кеширование, «VirtualDOM»? Несколько рендеров, чистые функции, персистентные хранилища. 39
  • 40. Попахивает функциональщиной... — Чистые функции (без энтропии); — запоминание результатов (мемоизация); — персистентные хранилища (immutable.js); — новый уровень абстракции. Может еще и параллелить? Камень зря простаивает. Temple? 40
  • 42. Дерево компонентов React JSX <SidebarComponent> <Logo image="/images/logo.svg" <Nav> <Link url="/events.html">События</Link> <Link url="/speakers.html">Люди</Link> </Nav> <SubscribeForm provider="mailchimp" id="ae74b08571" </SidebarComponent> Левая колонка moscowjs.ru 01. 02. 03. 04. 05. 06. 07. 08. 42
  • 43. Дерево компонентов в формате BEMJSON { block: 'SidebarComponent', content: [ { block: 'Logo', image: '/images/logo.svg' }, { block: 'Nav', content: [ { block: 'Link', url: '/events.html', content: 'События' }, { block: 'Link', url: '/speakers.html', content: 'Люди' }, ] }, { block: 'SubscribeForm', provider: 'mailchimp', id: 'ae74b08571' } ] } 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 43
  • 44. Идеальный веб-шаблонизатор — предметная ориентированность; — чистота шаблонов («сахар»); — модульность (частичная отрисовка); — легкий и быстрый рантайм; — чистота и независимость от внешней среды; — инфраструктура и удобство разработки; Nota bene: Скорость разработки VS масштабируемость VS поддержка. 44
  • 45. Предметно-ориентированные кандидаты — React JSX: императивный, JSX, VirtualDOM, строки и DOM; — BH: более декларативный, JS, чистый, строки или BEMJSON; — BEMHTML: еще более декларативный, свой/JS, чистый, строки; — Basis: смешанный, HTML+, строки и DOM; — Temple? 45
  • 47. Ссылки — youtu.be/7fFggu1fZIs — Лекция «Абстракция и декомпозиция. Декларативное программирование» — bit.ly/tplveged — Лекция «Про шаблонизаторы вообще, и BEMHTML в частности», Сергей Бережной — youtu.be/b0EF0VTs9Dc — EN: Лекция «Monads and Gonads», Crockford — bit.ly/tplcmp — Gist про сравнение шаблонизаторов 47
  • 48. Вопросы? Алексей Ярошевич, Dalee Digital Agency @zxqfox @yaroshevich qfox@ya.ru j.mp/ttmpl Шаблонизация, как дедушка завещал    48