Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BEMTREE and co. documentation package #500

Merged
merged 1 commit into from
Apr 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 339 additions & 0 deletions common.docs/bemjson/bemjson.ru.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
<a id="intro"></a>

### Введение

**Данный документ** представляет собой справочное руководство по формату описания входных данных BEMJSON.

В документе описаны:

* основные особенности BEMJSON, отличающие его от других форматов;
* синтаксис описания данных BEMJSON;


**Целевая аудитория документа** — веб-разработчики и HTML-верстальщики, использующие
[БЭМ-методологию](http://ru.bem.info/method/).

Предполагается, что читатель знаком с:

* HTML;
* JavaScript;
* CSS;
* БЭМ.


**В документе не описаны** средства гененерации БЭМ-дерева в формате BEMJSON.


<a id="common"></a>
###Общие понятия

В БЭМ-проектах для описания разметки веб-страницы в БЭМ-терминах вводится специальное понятие – **БЭМ-дерево**. Название выбрано по аналогии с DOM-деревом.

БЭМ-дерево – структура данных, которая описывает:

* структуру страницы – порядок и вложенность блоков;
* названия БЭМ-сущностей – имена блоков, элементов, модификаторов блока или элемента;
* состояния БЭМ-сущностей – наличие логических модификаторов, значения модификаторов;
* произвольные поля – вспомогательные данные (хеш-ключи, адреса публичных API и т.п.).

В библиотеке `bem-core` (и многих других БЭМ-проектах) стандартным форматом представления БЭМ-дерева является **BEMJSON** .

BEMJSON – структура данных (объект) JavaScript, с набором дополнительных соглашений о представлении БЭМ-сущностей.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

кажется, что уточнение про объект лучше убрать, т.к. bemjson может быть представлен строкой или массивом.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На уточнении настаивал Вегед. Лучше в следующей итерации добавитбь сведения про строку и массив.



<a id="bemcore"></a>
###BEMJSON и шаблонизация данных в bem-core
БЭМ-дерево в формате BEMJSON является неотъемлемой частью механизмов [шаблонизации данных](http://ru.bem.info/libs/bem-core/2.2.0/templating/templating), реализованных в `bem-core`. BEMJSON используется в качестве входных данных для шаблонизаторов:
* [BEMTREE](http://ru.bem.info/libs/bem-core/2.2.0/templating/bemtree#inputdata);
* [BEMHTML](http://ru.bem.info/libs/bem-core/2.2.0/templating/reference#inputdata).

В рамках BEMTREE и BEMHTML шаблонов фрагмент входных данных, относящийся к текущему элементу BEMJSON-дерева и его потомкам, содержится в поле контекста `this.ctx`.

***
**NB:** Шаблонизатор BEMTREE предназначен для генерации BEMJSON из произвольных данных.
***


<a id="sbor"></a>
###BEMJSON и сборка
Некоторые системы сборки, например [bem-tools](http://ru.bem.info/tools/bem/bem-tools/), используют файлы, содержащие литеральную запись BEMJSON, в качестве **декларации** сборки. В `bem-tools` для этих целей служат файлы с суффиксом `bemjson.js`. На основе БЭМ-дерева, описанного в этих файлах, система сборки определяет, набор БЭМ-сущностей, реализации которых должны быть собраны из папок блоков.

На практике это означает, что на основании декларации`bemjson.js` и настроек сборки сначала строится файл базовой декларации в формате `bemdecl.js`. Затем из него файл в формате `deps.js`, описывающий зависимости сборки. Файл зависимостей представляет собой плоский список БЭМ-сущностей, участвующих в сборке, вида:

```js
exports.deps = [
{
"block": "page",
"elem": "css"
},
{
"block": "page",
"elem": "js"
},
{
"block": "page",
"elem": "meta"
},
{
"block": "header"
},
{
"block": "content"
},
{
"block": "footer"
}
];
```

На основании файла зависимостей производится дальнейшая сборка файлов технологий из папок блоков, элементов и модификаторов, попадающих под декларацию. Файлы собираются в бандлы технологий на основании **суффиксов**.

Суффиксом считается часть имени файла следующая за первой точкой. Например в имени файла `index.bemjson.js` суффиксом является `bemjson.js`.

**См. также**:
* [Зависимости в bem-tools](http://ru.bem.info/tools/bem/bem-tools/depsjs/);
* [Сборка и подключение бандла технологий BEMTREE и BEMHTML](http://ru.bem.info/libs/bem-core/2.2.0/templating/templating#polymorph)



<a name="bemjson"></a>

### Синтаксис BEMJSON

<a id="datatype"></a>

#### Типы данных

Типы данных в BEMJSON соответствуют типам данных в JavaScript.

* Строки и числа:
* **Строка** `` 'a' `` `"a"`;
* **Число** `1` `0.1`;

Структура данных, состоящая из строки или числа, является валидным BEMJSON.

* **Объект** (ассоциативный массив) '{ключ: значение}' и остальные типы, кроме массива.

* **Массив** — список, может содержать элементы различных типов (строки, числа, объекты, массивы)
`[ "a", 1, {ключ: значение}, [ "b", 2, ... ] ]`.

<a id="fields_bemjson"></a>

#### Специальные поля BEMJSON

Для представления данных предметной области БЭМ и HTML в BEMJSON используются объекты, в которых зарезервированы
специальные имена полей.

<a name="notionbem"></a>

#####Представление БЭМ-сущностей

БЭМ-сущности представляются в BEMJSON в виде объектов, в которых могут присутствовать следующие поля:

<table>
<tr>
<th>Поле</th>
<th>Значение</th>
<th>Тип значения</th>
<th>Пример</th>
</tr>
<tr>
<td><code>block</code></td>
<td>Имя блока</td>
<td>Строка</td>
<td><code>{ block: 'menu' }</code></td>
</tr>

<tr>
<td><code>elem</code></td>
<td>Имя элемента</td>
<td>Строка</td>
<td><code>{ elem: 'item' }</code></td>
</tr>

<tr>
<td><code>mods</code></td>
<td>Модификаторы блока</td>
<td>Объект, содержащий имена и значения модификаторов в качестве пар ключ-значение:
<code>{имя_модификатора: 'значение_модификатора'}</code>
</td>
<td>
<pre><code>
{
block: 'link',
mods: { pseudo: true, color: 'green' }
}
</code></pre>
</td>
</tr>

<tr>
<td><code>elemMods</code></td>
<td>Модификаторы элемента</td>
<td>Объект, содержащий имена и значения модификаторов элемента в качестве пар ключ-значение:
<code>{имя_модификатора: 'значение_модификатора'}</code>
</td>
<td>
<pre><code>
{
elem: 'item',
elemMods: { selected: 'yes' }
}
</code></pre>
</td>
</tr>

<tr>
<td><code>mix</code></td>
<td>Подмешанные блоки/элементы</td>
<td>Массив, содержащий объекты, описывающие подмешанные блоки и элементы. В качестве значения может выступать
объект, который трактуется как массив, состоящий из одного элемента.</td>
<td>
<pre><code>
{
block: 'link',
mix: [ { block: 'serp-item', elem: 'link' } ]
}
</code></pre>
</td>
</tr>
</table>

**См. также**:

* [Достраивание БЭМ-сущностей по контексту](http://ru.bem.info/libs/bem-core/2.2.0/templating/templating#extensionbem)

<a name="notionhtml"></a>

##### Представление HTML

BEMJSON предоставляет возможность задавать некоторые аспекты выходного HTML непосредственно во входных данных.
Этой возможностью не следует злоупотреблять, т.к. BEMJSON представляет собой уровень данных, а непосредственное
оформление HTML должно выполняться на уровне шаблонизатора BEMHTML. Однако возможны ситуации, где оправданно
описание HTML-представления на уровне BEMJSON.


В BEMJSON предусмотрены следующие поля для непосредственного управления HTML-представлением:

<table>
<tr>
<th>Поле</th>
<th>Значение</th>
<th>Тип значения</th>
<th>Пример</th>
</tr>
<tr>
<td><code>tag</code></td>
<td>HTML-тег для данной сущности</td>
<td><code>String</code></td>
<td>
<pre><code>{
block: 'my-block',
tag: 'img'
}</code></pre>
</td>
</tr>
<tr>
<td><code>attrs</code></td>
<td>HTML-атрибуты для данной сущности</td>
<td><code>Object</code></td>
<td>
<pre><code>{
block: 'my-block',
tag: 'img',
attrs: { src: '//yandex.ru/favicon.ico', alt: '' }
}</code></pre>
</td>
</tr>
<tr>
<td><code>cls</code></td>
<td>Строка, добавляемая к HTML-атрибуту <code>class</code> (помимо автоматически генерируемых классов)</td>
<td><code>String</code></td>
<td>
<pre><code>{
block: 'my-block',
cls: 'some-blah-class'
}</code></pre>
</td>
</tr>
<tr>
<td><code>bem</code></td>
<td>Флаг — отменить генерацию БЭМ-классов в HTML-атрибуте <code>class</code> для данной сущности</td>
<td><code>Boolean</code></td>
<td>
<pre><code>{
block: 'page',
tag: 'html',
bem: false
}</code></pre>
</td>
</tr>
<tr>
<td><code>js</code></td>
<td>Либо флаг о наличии клиентского JavaScript у данной сущности, либо параметры JavaScript</td>
<td><code>Boolean</code></td>
<td>
<pre><code>{
block: 'form-input',
mods: { autocomplete: 'yes' },
js: {
dataprovider: { url: 'http://suggest.yandex.ru/...' }
}
}</code></pre>
</td>
</tr>
</table>

Обратите внимание, что имена и смысл полей BEMJSON, управляющих HTML-представлением, совпадают с именами и смыслом соответствующих [стандартных мод](http://ru.bem.info/libs/bem-core/2.2.0/templating/reference#standardmoda) BEMHTML (тег, атрибуты, класс и т.п.). В случае, если какие-то из аспектов выходного HTML заданы **и во входных данных, и в BEMHTML-шаблонах**, то более высокий приоритет имеют значения, заданные в BEMHTML-шаблонах.

При генерации HTML будет выполнено одно из двух действий:

* **Объединение** значений HTML-параметров, заданных в BEMJSON, cо значениями параметров, заданных в BEMHTML-шаблоне. Объединение значений производится только для тех параметров, для которых оно имеет очевидный смысл: `attrs`, `js`, `mix`.
* **Замещение** значений HTML-параметров, заданных в BEMJSON, значениями, заданными в **BEMHTML-шаблоне**. Выполняется для всех прочих значений: `tag`, `cls`, `bem`, `content`.

***
**NB** Приоритет BEMHTML-шаблонов позволяет **автору шаблонов** принимать решение, какие HTML-параметры будут приоритетнее в каждом конкретном случае — заданные в BEMHTML или в BEMJSON. Значения HTML-параметров, заданных в BEMJSON, доступны в шаблонах при обращении к фрагменту входного BEMJSON-дерева в контексте (поле `this.ctx`).
***

<a name="nesting"></a>

##### Вложенность: content

Для представления вложенных БЭМ-сущностей (БЭМ-дерева) в BEMJSON зарезервировано поле `content`. В качестве значения
данного поля может выступать произвольный BEMJSON:

* Примитивный тип (строка, число). Значение используется в качестве содержимого (текста) HTML-элемента, соответствующего
контекстной сущности.
* Объект, описывающий БЭМ-дерево. Значение используется для генерации HTML-элементов, вложенных в HTML-элемент,
соответствующий контекстной сущности.

Уровень вложенности дерева БЭМ-сущностей, построенного с помощью поля `content`, не ограничен.



<a id="custom_fields"></a>

##### Произвольные поля

Помимо специальных полей, описывающих БЭМ-сущность и ее HTML-представление, в том же объекте могут присутствовать
любые поля с произвольными данными, которые будут доступны для использования в шаблонах BEMHTML или BEMTREE.

Примером произвольного поля может служить поле `url` в блоке ссылки:

```js
{
block: 'link',
url: '//yandex.ru'
}
```

Пример использования данных из произвольного поля см. в разделе: [Выбор шаблона по условию](http://ru.bem.info/libs/bem-core/2.2.0/templating/reference#select_template) из документации по BEMHTML.

<a name="customjs"></a>

#### Произвольный JavaScript в BEMJSON

BEMJSON является менее ограниченным форматом, чем JSON. Произвольные JavaScript-выражения будут валидным BEMJSON.

Специфика BEMJSON как формата данных заключается в соблюдении описанных в предшествующих разделах соглашений
по именованию полей в объектах (для представления БЭМ-сущностей и HTML-представления) и правил вложения объектов.
Loading