Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Сергей Бережной — Шаблонизаторы
Next
Download to read offline and view in fullscreen.

1

Share

Download to read offline

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

Download to read offline

Доклад руководителя группы разработки агентства ДАЛЕЕ Алексея Ярошевича на DevConf 2015

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

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

  1. 1. Шаблонизация Как дедушка завещал Алексей Ярошевич @zxqfox @yaroshevich qfox@ya.ru   
  2. 2. План вещания — Немножко теории — «Родословная» шаблонизаторов — Веления и предписания — Взгляд изнутри — Идеальный шаблонизатор 2
  3. 3. Немножко теории
  4. 4. Шаблоны — схема преобразования данных из одного формата в другой. Функция (отображение, оператор, преобразование) — связь между элементами множеств.““ 4
  5. 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
  6. 6. «Родословная» шаблонизаторов и их полезности
  7. 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. 8. Полезности — Декомпозиция и DRY — разделение кода на куски; — отделение view от логики (MVC? не, не слышал); — простота и красота — синтаксический «сахар»; — «царапки» — защита от дурака; — хелперы — вспомогательные методы для вывода. Как итог: разделение ответственности и новая профессия. 8
  9. 9. Веления и предписания
  10. 10. Веления или императивный подход — Представители: Assembler, C, JavaScript; — Процесс описывается инструкциями; — интенсивно используется присваивание; — И исполняется последовательно. class Employee extends Person { Declaration, right? constructor(name) { super.constuctor(name); } } 01. 02. 03. 04. 05. 10
  11. 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. 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. 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. 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. 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. 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. 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. 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. Проблемы императивного подхода — Несоразмерный рост сложности модели вычислений; — предсказать результат работы — крайне сложно; — большинство таких шаблонизаторов — синтаксический «сахар». Ой-ой. 19
  20. 20. Предписания или декларативный подход — Представители: HTML, CSS, SQL, XSLT; — описывают желаемые результаты, а не процесс их достижения; — часто детерминированность и функциональная чистота; — порядок инструкций в блоке не важен. XML + XSLT— наше все? Структурированный JSON + Plates, Yate, BEMXJST, BH — тоже вариант. 20
  21. 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. 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. 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. 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. 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. 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. Проблемки декларативного подхода? — Входные данные нужно готовить; — сносит голову — функциональщина близко; — медленнее, при использовании в лоб. 27
  28. 28. Еще раз о различиях Императив — Последовательное исполнение — Описывается процесс — Циклы и условия — Присваивание переменных Декларатив — Порядок не важен — Описывается результат — Цепочки вызовов примитивов — Монады и гонады Любая программа балансирует между императивом и декларативом. 28
  29. 29. Нюансы
  30. 30. Строковые vs DOM-шаблонизаторы — Строковые на клиенте — медленно; — DOM-шаблонизаторы на сервере — боль. Хороший шаблонизатор должен быть многостаночником. 30
  31. 31. Предметная ориентация Разделение классического подхода на 2 преобразования. — Построение view-ориентированной структуры (энтропия, грязные функции, получение данных из окружения); — Преобразование в HTML-строку с разметкой сущностей; — Преобразование в DOM-ноды на клиенте. Компоненты — абстракция в различных технологиях над DOM. 31
  32. 32. 32
  33. 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. 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. 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
  36. 36. Взгляд изнутри
  37. 37. Компиляция и среда выполнения Компиляция — преобразование кода шаблонов в исполняемый код. «Рантайм» — запускает код или предоставляет функционал. — Статический анализ — проверяет, структуризует и ускоряет код; — декларативный код — проще разбирается, шире маневр. Императивность в деталях — допустима, но чувствуйте грань. 37
  38. 38. Энтропия и побочные-эффекты Примеры: Date , Math.random , XHR.* , global.* . — Медленнее; — проблемы с отладкой (и тестами); — нельзя параллелить; — нельзя кешировать. Непредсказуемы, что с них взять? В мусор! 38
  39. 39. Изоморфизм Рендеринг одних шаблонов и на сервере, и на клиенте. — 2 среды выполнения — для каждого окружения; — 1 среда выполнения ( !), и компиляция; — Компиляция вместе с «рантаймом» (жыр). DOM-деревья, кеширование, «VirtualDOM»? Несколько рендеров, чистые функции, персистентные хранилища. 39
  40. 40. Попахивает функциональщиной... — Чистые функции (без энтропии); — запоминание результатов (мемоизация); — персистентные хранилища (immutable.js); — новый уровень абстракции. Может еще и параллелить? Камень зря простаивает. Temple? 40
  41. 41. Живой пример 41
  42. 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. 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. 44. Идеальный веб-шаблонизатор — предметная ориентированность; — чистота шаблонов («сахар»); — модульность (частичная отрисовка); — легкий и быстрый рантайм; — чистота и независимость от внешней среды; — инфраструктура и удобство разработки; Nota bene: Скорость разработки VS масштабируемость VS поддержка. 44
  45. 45. Предметно-ориентированные кандидаты — React JSX: императивный, JSX, VirtualDOM, строки и DOM; — BH: более декларативный, JS, чистый, строки или BEMJSON; — BEMHTML: еще более декларативный, свой/JS, чистый, строки; — Basis: смешанный, HTML+, строки и DOM; — Temple? 45
  46. 46. Тигр
  47. 47. Ссылки — youtu.be/7fFggu1fZIs — Лекция «Абстракция и декомпозиция. Декларативное программирование» — bit.ly/tplveged — Лекция «Про шаблонизаторы вообще, и BEMHTML в частности», Сергей Бережной — youtu.be/b0EF0VTs9Dc — EN: Лекция «Monads and Gonads», Crockford — bit.ly/tplcmp — Gist про сравнение шаблонизаторов 47
  48. 48. Вопросы? Алексей Ярошевич, Dalee Digital Agency @zxqfox @yaroshevich qfox@ya.ru j.mp/ttmpl Шаблонизация, как дедушка завещал    48
  • knefedov

    Jun. 21, 2015

Доклад руководителя группы разработки агентства ДАЛЕЕ Алексея Ярошевича на DevConf 2015

Views

Total views

683

On Slideshare

0

From embeds

0

Number of embeds

6

Actions

Downloads

2

Shares

0

Comments

0

Likes

1

×