Сергей Бережной "Экзотическая шаблонизация, или как...
DESCRIPTION
Существует большое количество разных HTML-шаблонизаторов, и, зная это, мы написали свой, экзотический! Мы расскажем о том, что получилось в итоге и зачем мы это сделали. А также подробнее остановимся на синтаксисе, семантике, оптимизации и компиляции шаблонов в эффективный JavaScript.TRANSCRIPT
руководитель отделаразработки поисковых интерфейсов
Экзотическая шаблонизацияили как писать HTML для блоков
Сергей Бережной
Вступление
Кто я?
Вступление
Кто я?
• Разработчик интерфейсов Яндекса с 2005 года• Руководитель отдела разработки поисковых интерфейсов• БЭМ-соавтор
4
@veged
github.com/veged
Кто вы?
Вступление
Основная часть
Классика
Основная часть
Классика
8
{ settings: { weather: true, traffic: false }, weather: { temp: 4 }, traffic: { level: 2 }}
Классика
9
<ul> [% IF settings.weather %] <li>[% weather.temp %]</li> [% END %] [% IF settings.traffic %] <li>[% traffic.level %]</li> [% END %]</ul>
Классика
10
Data → HTML
Классика
11
Альтернатива
Основная часть
{ settings: { weather: true, traffic: false }, weather: { temp: 4 }, traffic: { level: 2 }}
Альтернатива
13
var items = [];
if(settings.weather) items.push({ elem: 'item', content: weather.temp });
if(settings.traffic) items.push({ elem: 'item', content: traffic.level });
return { block: 'menu', content: items };
Альтернатива
14
{ block: 'menu', content: [ { elem: 'item', content: 4 } ]}
Альтернатива
15
block menu { tag: 'ul' elem item, tag: 'li'}
Альтернатива
16
<ul class="menu"> <li class="menu__item"> +4 °С </li></ul>
Альтернатива
17
Data → View → HTML
Альтернатива
18
Data → БЭМ-дерево → HTML
Альтернатива
19
Data → БЭМ-дерево ⤙BEMHTML⤚ HTML
Альтернатива
20
Альтернатива
• блоки рисуются сами
21
Альтернатива
• блоки рисуются сами• не нужна интеграция нового HTML в шаблоны
22
<ul> [% IF settings.weather %] <li>[% weather.temp %]</li> [% END %] [% IF settings.traffic %] <li>[% traffic.level %]</li> [% END %]</ul>
Альтернатива
23
Альтернатива
• блоки рисуются сами• не нужна интеграция нового HTML в шаблоны• можно прототипировать HTML/CSS без реальных данных
24
Data → БЭМ-дерево → HTML
Альтернатива
25
Data → БЭМ-дерево → HTML
Альтернатива
26
Альтернатива
• блоки рисуются сами• не нужна интеграция нового HTML в шаблоны• можно прототипировать HTML/CSS без реальных данных• меньше копипаста, больше повторного использования
27
<ul> [% IF settings.weather %] <li>[% weather.temp %]</li> [% END %] [% IF settings.traffic %] <li>[% traffic.level %]</li> [% END %]</ul>
Альтернатива
28
block menu { tag: 'ul' elem item, tag: 'li'}
Альтернатива
29
Альтернатива
• блоки рисуются сами• не нужна интеграция нового HTML в шаблоны• можно прототипировать HTML/CSS без реальных данных• меньше копипаста, больше повторного использования• очень похоже на CSS
30
block menu { tag: 'ul' elem item, tag: 'li'}
Альтернатива
31
/* CSS */.header { font-size: 140%;}
// BEMHTMLblock header, tag: 'h1'
Альтернатива
32
Файлы
Основная часть
blocks/
Файлы
34
blocks/ header/ menu/
Файлы
35
blocks/ header/ menu/ __item/
Файлы
36
blocks/ header/ header.css menu/ __item/ menu__item.css menu.css
Файлы
37
blocks/ header/ header.css header.bemhtml menu/ __item/ menu__item.css menu__item.bemhtml menu.css menu.bemhtml
Файлы
38
blocks/pages/
Файлы
39
blocks/pages/ index/
Файлы
40
blocks/pages/ index/ index.css
Файлы
41
pages/index/index.css
@import url(../../blocks/header/header.css);@import url(../../blocks/menu/menu.css);@import url(../../blocks/menu/__item/menu__item.css);
Файлы
42
bem build --output-name=index --decl=pages/index/index.bemdecl.js --level=blocks/ --tech=css
Файлы
43
blocks/pages/ index/ index.bemdecl.js // декларация
Файлы
44
bem build --output-name=index --decl=pages/index/index.bemdecl.js --level=blocks/ --tech=css --tech=bemhtml
Файлы
45
blocks/pages/ index/ index.bemdecl.js // декларация
Файлы
46
blocks/pages/ index/ index.bemdecl.js // декларация index.css // сборка index.bemhtml.js // сборка
Файлы
47
Переопределения
Основная часть
/* CSS */.header { font-size: 140%; font-weight: bold;}
Переопределения
50
<!-- HTML --><h1 class="header"> Заголовок 1</h1>
Переопределения
51
// BEMHTMLblock header, tag: 'h1'
Переопределения
52
blocks/ header/ header.css header.bemhtml
Переопределения
53
/* CSS */
.header { font-size: 140%; font-weight: bold;}
.header_level_2 { font-size: 120%;}
Переопределения
54
blocks/ header/ _level/ header_level_2.css header.css
Переопределения
55
<!-- HTML --><h2 class="header header_level_2"> Заголовок 2</h2>
Переопределения
56
// BEMHTML
block header, tag: 'h1'
block header, mod level 2, tag: 'h2'
Переопределения
57
blocks/ header/ _level/ header_level_2.css header_level_2.bemhtml header.css header.bemhtml
Переопределения
58
pages/index/index.css
@import url(../../blocks/header/header.css);@import url(../../blocks/header/_level/header_level_2.css);
Переопределения
59
mylib/ blocks/ header/ _level/ header_level_2.css header_level_2.bemhtml header.css header.bemhtml
Переопределения
60
mylib/ blocks/ header/ _level/ header_level_2.css header_level_2.bemhtml header.css header.bemhtmlblocks/
Переопределения
61
/* CSS */.header { font-weight: normal;}
Переопределения
62
<!-- HTML -->
<h2 class="header"> Заголовок 1</h2>
<h3 class="header header_level_2"> Заголовок 2</h3>
Переопределения
63
// BEMHTML
block header, tag: 'h2'
block header, mod level 2, tag: 'h3'
Переопределения
64
mylib/blocks/ header/ _level/ header_level_2.bemhtml header.css header.bemhtml
Переопределения
65
bem build --output-name=index --decl=pages/index/index.bemdecl.js --level=blocks/ --tech=css --tech=bemhtml
Переопределения
66
bem build --output-name=index --decl=pages/index/index.bemdecl.js --level=mylib/blocks/ --level=blocks/ --tech=css --tech=bemhtml
Переопределения
67
pages/index/index.css
@import url(../../mylib/blocks/header/header.css);@import url(../../blocks/header/header.css);
Переопределения
68
Многопроходность
Основная часть
<ul class="menu"> <li class="menu__item"> +4 °С </li></ul>
Многопроходность
70
{ block: 'menu', content: [ { elem: 'item', content: 4 } ]}
Многопроходность
71
block menu { tag: 'ul' elem item, tag: 'li'}
Многопроходность
72
<ul class="menu"> <li class="menu__item"> <span class="menu__item-wrap"> +4 °С </span> </li></ul>
Многопроходность
73
block menu { tag: 'ul' elem item, tag: 'li' elem item-wrap, tag: 'span'}
Многопроходность
74
{ block: 'menu', content: [ { elem: 'item', content: { elem: 'item-wrap', content: 4 } } ]}
Многопроходность
75
block menu { tag: 'ul' elem item { tag: 'li' content: { elem: 'item-wrap', content: applyNext() } } elem item-wrap, tag: 'span'}
Многопроходность
76
{ block: 'menu', content: [ { elem: 'item', content: 4 } ]}
Многопроходность
77
<ul class="menu"> <li class="menu__item"> <span class="menu__item-wrap"> +4 °С </span> </li></ul>
Многопроходность
78
JavaScript
Основная часть
JavaScript
80
JavaScript
81
{ block: 'ya-user', content: 'veged'}
JavaScript
82
<a class="ya-user" href="//i.yandex.ru"> <span class="ya-user__first"> v </span> eged</a>
JavaScript
83
block ya-user { tag: 'a' attrs: { href: '//i.yandex.ru' }
elem first, tag: 'span'}
JavaScript
84
{ block: 'ya-user', content: [ { elem: 'first', content: 'v' }, 'eged' ]}
JavaScript
85
block ya-user, content: { var oldContent = applyNext(); return [ { elem: 'first', content: oldContent[0] }, oldContent.substring(1) ]}
JavaScript
86
{ block: 'ya-user', content: 'veged'}
JavaScript
87
<a class="ya-user" href="//i.yandex.ru"> <span class="ya-user__first"> v </span> eged</a>
JavaScript
88
Скорость
Основная часть
Secinājums
Secinājums
• декларативность
92
Secinājums
• декларативность• блоки рисуются сами
92
Secinājums
• декларативность• блоки рисуются сами• переопределения
92
Secinājums
• декларативность• блоки рисуются сами• переопределения• многопроходность
92
Secinājums
• декларативность• блоки рисуются сами• переопределения• многопроходность• БЭМ
92
Secinājums
• существуют другие способы писать шаблоны
93
Secinājums
• существуют другие способы писать шаблоны• попробовать БЭМ: github.com/bem/project-stub
93
Secinājums
• существуют другие способы писать шаблоны• попробовать БЭМ: github.com/bem/project-stub• попробовать: XSLT, XJST, написать своё
93
руководитель отделаразработкипоисковых интерфейсов
Спасибо
Сергей Бережной
@veged
github.com/veged