Upload
alexey-ivanov
View
272
Download
2
Embed Size (px)
Citation preview
Структура доклада1. Стандартный подход к организации верстки и его проблемы
2. Пути решения этих проблем
3. Холивар!
listing.html:
div.listing
div.listing__header
div.listing__breadcrumbs
= render breadcrumbs.slim", items: page.breadcrumbs
h1.listing__title= page.title
div.listing__sorting
= render "sorting.slim", items: page.sorting
div.listing__content
div.listing__items
= render "goods.slim", items: page.goods
div.listing__nav
= render "filters.slim", items: page.filters
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
listing.html:
// ...
div.listing__content
div.listing__items
= render "goods.slim",
items: page.goods,
banners: page.banners
01.
02.
03.
04.
05.
06.
goods.html:
div.goods
- items.each_with_index do |item, i|
- if i%3 == 0
= render "banner.slim", item: banners[i/3-1]
= render "good.slim", item: item
01.
02.
03.
04.
05.
listing.html:
div.listing__view-mode
= render "view-mode.slim", items: page.viewMode
// ...
div.listing__items
= render "goods.slim",
items: page.goods,
banners: page.banner,
mode: page.mode
div.listing__nav
- if page.categories
= render "categories.slim", items: page.categories
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
goods.html:
div.goods
- items.each_with_index do |item, i|
- if type == list
- if i % 3 == 0
= render "banner.slim", item: banners[i/3-1]
= render "good.slim", item: item
- elsif
- if (i+1)%6 == 0
= render "banner.slim", item: banners[(i+1)/6-1]
= render "grid-good.slim", item: item
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
Что можно сделать в такойситуации?
— Добавить еще пять условий в шаблоны, чтобы избежать копипаста.
— Решить, что нервы дороже и разнести все это на несколько
шаблонов с повторяющимися элементами.
— Пойти другим путем.
Что хочется1. Разделять структуру страницы и шаблоны отдельных компонентов
2. Использовать один шаблон на разных страницах с разными детьми.
3. Работать без передачи в шаблон всей информации о его потомках и
их логике работы.
Варинты другого пути— Extend’ы – путь Django Templates, Twig и производных.
— Block/Yield – путь haml, Slim, erb и отчасти Jade.
— Псевдотеги и их разворачивание – путь XSLT и его потомков.
layout.html:
<div class="listing">
//...
<div class="listing__content">
<div class="listing__items">
{% block items %}{% endblock %}
</div>
<div class="listing__nav">
{% block nav %}{% endblock %}
</div>
</div>
</div>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
grid.html:
{% extends "listing.html" %}
{% block items %}
{% for item in items %}
//...
{% endfor %}
{% endblock %}
{% block nav %}
//...
{% endblock %}
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
page.slim:
= render :layout => 'listing.slim', title: title do
= render :layout => 'goods.slim' do
- items.each do |item|
//...
= render :layout => 'nav.slim' do
//...
goods.slim:
div.goods
= yield
01.
02.
03.
04.
05.
06.
01.
02.
page.xml:
<listing title={{title}}>
<breadcrumbs items="{{breadcrumbs}}" />
<goods>
// ...
goods.xslt:
<xsl:template match="goods">
<div class="goods">
<xsl:copy-of select="node()"/>
</div>
</xsl:template>
01.
02.
03.
04.
01.
02.
03.
04.
05.
Чем же они хороши1. Создают компоненты со всем зависимостями.
2. Строят дерево страницы из созданных ранее компонентов.
3. Позволяют вкладывать компоненты друг в друга.
4. Могут работать как на клиенте, так и на сервере.
5. Позволяют описать логику поведения на JS.
6. Дают публичный API для компонента.
Примеры шаблонов сприменением разныхтехнологийhttps://github.com/iAdramelk/dump‐2015‐demo/
page.html:
<x-listing-nav>
<x-categories items='[...]'></x-categories>
<x-facets>
<x-facet xtitle='Цена, руб.' closed>
<x-price min='900' max='20000'></x-price>
</x-facet>
<x-facet xtitle='Основной материал'>
<x-checkbox-list items='[...]'></x-checkbox-list>
</x-facet>
//...
</x-facets>
</x-listing-nav>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
facet.html:
<polymer-element name="x-facet"
attributes="xtitle closed">
<template>
<link rel="stylesheet" href="facet.css">
<div class="title"></div>
<div class="content">
<content></content>
</div>
</template>
<script src="facet.js"></script>
</polymer-element>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
Особенности— Черновик спецификации для браузера.
— Shadow DOM.
— Не требует прекомпиляции.
— Несколько точек для вставки детей с выбором по css‐селекторам.
listing.html:
//...
<div class="header">
<h1 class="title">{{xtitle}}</h1>
<div class="sorting">
<content select="x-sorting, x-lead"></content>
</div>
</div>
<div class="content">
<div class="items">
<content select="x-listing-main"></content>
</div>
//...
</div>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
listing.html:
<x-listing xtitle='Заголовок'>
<x-breadcrumbs items="[...]"></x-breadcrumbs>
<x-sorting items="[...]"></x-sorting>
<x-view-mode items="[...]"></x-view-mode>
<x-listing-main>
//...
</x-listing-main>
</x-listing>
01.
02.
03.
04.
05.
06.
07.
08.
Проблемы и ограничения— Везде кроме Google Chrome нужен полифил.
— Полифил медленный и заметно тормозит загрузку страницы.
— Не работает в IE до 10 версии.
page.jsx:
<Listing.Nav>
<Categories items=[...] />
<Facets>
<Facet title="Цена, руб." closed={true}>
<Price min="900" max="20000" />
</Facet>
<Facet title="Основной материал">
<CheckboxList items=[...] />
</Facet>
//...
</Facets>
</Listing.Nav>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
facet.jsx:
var Facet = React.createClass({
componentDidMount: function() {},
render: function() { return (
<div className="facet">
<div className="facet__title">
{this.props.title}
</div>
<div className="facet__content">
{this.props.children}
</div>
</div>
); }
});
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
Особенности— Создан для быстрой шаблонизации в браузере.
— Свой синтаксис для компиляции в JavaScript.
— Очень быстрый, обновляет страницу с минимальными
перерисовками.
— Генерирует html на сервере как с data‐binding’ами, так и без.
Проблемы и ограничения— Большой вес скомпилированных шаблонов.
— Необходимос грузить все шаблоны в браузер для работы data‐
binding’ов.
page.html:
<listing-nav>
<categories items="[...]"></categories>
<facets>
<facet title="Цена, руб." closed="{true}">
<price min="900" max="20000"></x-price>
</facet>
<facet title="Основной материал">
<checkbox-list items="[...]"></checkbox-list>
</facet>
//...
</facets>
</listing-nav>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
facet.tag:
<facet>
<div class="facet{opts.closed ? ' is-closed' : ''}">
<div class="facet__title">{opts.title}</div>
<div class="facet__content">
<inner-html/>
</div>
</div>
this.ready = function() { ... };
</facet>
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
Проблемы и ограничения— Меньше возмонжостей по сравнению со всем остальным.
— Нет серверного рендеринга.
— Оставляет теги, использованные для разметки.
— Нет работающего из коробки способа вставлять теги в теги. Нужно
создавать свой плагин для этого.
— Совсем новый и слабо обкатан.
Как работает BEM— ENB запускает и генерирует все.
— BEMTREE трансформируется в BEMJSON.
— На BEMJSON применяются трансформации из BEMHTML или BH.
— На выходе полученный BEMJSON компилируется в HTML.
page.bemtree:
block('page').mod('bundle', 'listing-list')(
content()(function() {
return [ {
block: 'facets',
content: {
block: 'facet', title: data.title, closed: true,
content: {
block: 'price', min: data.min, max: data.max
}
}
} ]
})
);
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
13.
page.bemjson:
( {
block: 'facets',
content: {
block: 'facet', title: "Размер", closed: true,
content: {
block: 'price', min: 900, max: 20000
}
}
} )
01.
02.
03.
04.
05.
06.
07.
08.
09.
facet.bh.js:
module.exports = function(bh) {
bh.match('facet', function(ctx, json) {
ctx.content({
block : 'facet',
elemMods: { 'closed': json.closed },
content: [
{ elem: 'title', content: json.price },
{ elem: 'content', content: json.content }
]
});
});
};
01.
02.
03.
04.
05.
06.
07.
08.
09.
10.
11.
12.
Особенности— Умеет почти все. Генерировать статику, работать в браузере, делать
логику для блоков без необходимости тащить с собой все шаблоны,
работать с любыми типами данных, и так далее.
— Можно переназначать не только блоки целиком, но и отдельные
элементы в них.
Проблемы и ограничения— Нельзя брать по частям.Сразу подписываетесь на весь стек.
— Очень высокий порог вхождения.
Что и где можно использоватьуже сейчас
— Web Components и Polymer – проекты заточенные под Chrome и
Chrome OS.
— React – SPA, с необходимостью предзагрузки.
— Riot – SPA с одной точкой входа.
— BEM – везде, если сможете разобраться.
Холивар?— Алексей Иванов, Злые Марсиане
— Twitter: @iadramelk
— Github: @iadramelk
— Примеры и слайды:
https://github.com/iAdramelk/dump‐2015‐demo