<commit_before><a name="intro"></a>

## Введение

**Данный документ** представляет собой справочное руководство по шаблонизации данных в `bem-core`.

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

* основные особенности BEMHTML и BEMTREE, отличающие их от других шаблонизаторов;
* синтаксис шаблонов BEMHTML и BEMTREE;
* порядок обработки входных данных и генерации HTML.

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

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

* HTML
* JavaScript
* CSS
* БЭМ


**В документе не описаны** специфические для BEMTREE и BEMHTML моды и поля контекста, настройки сборки, поставщики данных.


<a name="main"></a>
## Общие сведения

Под **шаблонизацией** в bem-core понимается процесс генерации HTML из некоторых входных данных.

В `bem-core` реализован механизм двухэтапной шаблонизации данных. На первом этапе нормализованные данные, получаемые от бэкенда, преобразуются к view-ориентированному представлению.  Эту функцию выполняет шаблонизатор [BEMTREE](https://ru.bem.info/technology/bemtree/).

BEMTREE формирует **БЭМ-дерево** в формате BEMJSON. БЭМ-дерево описывает:

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

На втором этапе ранее сформированный BEMJSON поэлементно преобразуется в HTML. Эту функцию выполняет шаблонизатор [BEMHTML](https://ru.bem.info/technology/bemhtml/current/reference/).

Для каждой БЭМ-сущности создаются HTML-тэги, классы и атрибуты, в соответствии с  BEMHTML-шаблонами для этой сущности.

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



<a name="bemx_arch"></a>
## Архитектура шаблонизаторов BEMHTML и BEMTREE

Для обработки BEMTREE- и BEMHTML-шаблонов используется модуль [bem-xjst](https://ru.bem.info/tools/templating-engines/bemxjst/).
BEM-XJST является надмножеством [языка шаблонов XJST](https://github.com/veged/xjst), который, в свою очередь, является надмножеством JavaScript.

BEM-XJST — это набор БЭМ-ориентированных хелперов, расширяющий
стандартный XJST-синтаксис. В нем определены:

  * хелперы для записи подпредикатов, относящихся к предметной области БЭМ;
  * хелперы для определения подпредиката по моде;
  * хелперы для применения XJST-конструкций `apply` и `applyNext` по произвольной моде;
  * конструкцию [applyCtx](#applyctx).

BEM-XJST реализует наиболее общую схему обработки шаблонов. Логика, специфическая для каждого из шаблонизаторов в отдельности, реализована на уровне их **базовых шаблонов**.

Базовый шаблон – это реализация блока `i-bem` в технологии
 соответствующего шаблонизатора:

* для BEMTREE — [i-bem.bemtree](https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/i-bem.bemtree);
* для BEMHTML — [i-bem.bemhtml](https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/i-bem.bemhtml).

Базовый шаблон определяет:
* набор и порядок выполнения доступных для технологии стандартных [мод](#moda);
* [поля контекста](#context_field);

Можно выделить четыре уровня абстракции, на каждом из которых реализуется часть совокупной логики шаблонизатора:

1. XJST
2. BEM-XJST
3. Базовый шаблон
4. Пользовательский шаблон

Каждый последующий уровень использует  логику, реализованную на предыдущем и дополняет (переопределяет) ее:

* XJST предоставляет базовые конструкции для:
	* проверки истинности подпредикатов (`match`);
	* выполнения тела шаблона в модифицированном контексте (`local` и `apply`).
* BEM-XJST реализует:
	* логику, относящуюся к предметной области БЭМ – хелперы для записи подпредикатов для блоков, элементов, модификаторов;
	* логику для работы с фрагментом входного БЭМ-дерева (поле контекста `this.ctx`) и конструкцию `applyCtx`, предназначенную для его модификации;
	* возможность вызывать `apply`  по моде;
	* общую схему обработки шаблонов.
* Базовый шаблон реализует логику, специфическую для конкретной технологии:
	* набор стандартных мод;
	* поля контекста.

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

![levels](https://raw.githubusercontent.com/Murdalay/bem-core/feature_doc/common.docs/templating/template-levels.png)


<a name="bemx_intro"></a>
### Знакомство с BEM-XJST-шаблонизаторами

Как следствие использования описанной выше архитектуры, синтаксис BEMHTML и BEMTREE почти идентичен. Вся разница между ними заключается в:
* количестве доступных стандартных мод;
* нескольких полях контекста, специфических для каждого из шаблонизаторов.


Общие для BEMHTML и BEMTREE синтаксические конструкции и поля контекста объединены понятием **BEM-XJST-синтаксис**.

Шаблонизаторы, поддерживающие синтаксические конструкции и поля контекста, соответствующие BEM-XJST-синтаксису, называются **BEM-XJST-шаблонизаторами**.



<a name="bemx_basic"></a>
## Особенности BEM-XJST-шаблонизаторов

<a name="bem_area"></a>
### Привязка к БЭМ-предметной области

Шаблонизаторы BEMHTML и BEMTREE входят в связку технологических решений, обеспечивающих создание веб-интерфейсов в рамках
[БЭМ-методологии](https://ru.bem.info/method/).

Входные данные шаблонизатора — БЭМ-дерево в формате [BEMJSON](https://ru.bem.info/technology/bemjson/current/bemjson/), описывающее веб-страницу.
Языки шаблонов BEMHTML и BEMTREE предлагают специальные конструкции для обработки блоков, элементов и модификаторов.


<a name="decl_templatе"></a>

### Декларативные шаблоны

Ниже рассматриваются особенности декларативного подхода к созданию шаблонов на примере шаблонизатора BEMHTML.

Все эти особенности относятся и к шаблонизатору BEMTREE с той оговоркой, что результатом выполнения BEMTREE-шаблонов будет BEMJSON вместо HTML.


<a name="imperativ"></a>

#### Императивный подход

Традиционные шаблонизаторы предлагают **императивный подход** к написанию шаблонов: HTML формируется в процессе
последовательного чтения и выполнения шаблона.

<table>
<tr>
    <th>Входные данные</th>
    <th>Шаблон</th>
    <th>Результат</th>
</tr>
<tr>
    <td>
        <pre><code>
{
  items: [
    { text: '1' },
    { text: '2' }
  ]
}
        </code></pre>
    </td>

    <td>
        <pre><code>
&lt;ul class="menu"&gt;
    [% foreach item in items %]
        &lt;li class="menu__item"&gt;
            [% item.text %]
        &lt;/li&gt;
    [% end %]
&lt;/ul&gt;
        </code></pre>
    </td>
    <td>
        <pre><code>
&lt;ul class="menu"&gt;
    &lt;li class="menu__item">1&lt;/li&gt;
    &lt;li class="menu__item">2&lt;/li&gt;
&lt;/ul&gt;
        </code></pre>
    </td>

</tr>
</table>

В таком шаблоне неизбежна избыточность, вызванная синтаксическими требованиями HTML: *вывести открывающий
тег — сгенерировать содержимое — вывести закрывающий тег*. Еще выше избыточность в таблицах, списках и т.п.


<a name="declarativ"></a>

#### Декларативный подход

**Декларативный подход** позволяет формулировать шаблоны как набор простых утверждений вида: *тип входных данных (БЭМ-сущность) — HTML-представление (тег, атрибут и т.п.)*.

<table>
    <tr>
        <th>Входные данные</th>
        <th>Шаблон</th>
        <th>Результат</th>
    </tr>
    <tr>
        <td>
        <pre><code>
{
    block: 'menu',
    content: [
        { elem: 'item', content: '1' },
        { elem: 'item', content: '2' }
    ]
}
        </code></pre>
        </td>
        <td>
        <pre><code>
block('menu')(
    tag()('ul'),
    elemMatch('item').tag()('li')
)
        </code></pre>
        </td>
        <td>
        <pre><code>
&lt;ul class="menu"&gt;
    &lt;li class="menu__item"&gt;1&lt;/li&gt;
    &lt;li class="menu__item"&gt;2&lt;/li&gt;
&lt;/ul&gt;
        </code></pre>
        </td>
    </tr>
</table>


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


<a name="language"></a>

### Язык описания и исполнения шаблонов — JavaScript

Шаблонизаторы BEMHTML и BEMTREE представляют собой специализированный язык (DSL), **расширяющий** JavaScript.

В шаблонах могут использоваться **любые** JavaScript-конструкции.

Перед выполнением шаблоны компилируется в оптимизированный JavaScript, который принимает BEMJSON и возвращает HTML для BEMHTML и BEMJSON для BEMTREE.

Такой шаблон может выполняться как на стороне сервера, так и на стороне клиента.


<a name="restrictions"></a>

### Ограничения на уровне соглашений
<commit_msg>Correct special characters<commit_after><a name="intro"></a>

## Введение

**Данный документ** представляет собой справочное руководство по шаблонизации данных в `bem-core`.

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

* основные особенности BEMHTML и BEMTREE, отличающие их от других шаблонизаторов;
* синтаксис шаблонов BEMHTML и BEMTREE;
* порядок обработки входных данных и генерации HTML.

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

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

* HTML
* JavaScript
* CSS
* БЭМ


**В документе не описаны** специфические для BEMTREE и BEMHTML моды и поля контекста, настройки сборки, поставщики данных.


<a name="main"></a>
## Общие сведения

Под **шаблонизацией** в bem-core понимается процесс генерации HTML из некоторых входных данных.

В `bem-core` реализован механизм двухэтапной шаблонизации данных. На первом этапе нормализованные данные, получаемые от бэкенда, преобразуются к view-ориентированному представлению.  Эту функцию выполняет шаблонизатор [BEMTREE](https://ru.bem.info/technology/bemtree/).

BEMTREE формирует **БЭМ-дерево** в формате BEMJSON. БЭМ-дерево описывает:

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

На втором этапе ранее сформированный BEMJSON поэлементно преобразуется в HTML. Эту функцию выполняет шаблонизатор [BEMHTML](https://ru.bem.info/technology/bemhtml/current/reference/).

Для каждой БЭМ-сущности создаются HTML-тэги, классы и атрибуты, в соответствии с  BEMHTML-шаблонами для этой сущности.

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



<a name="bemx_arch"></a>
## Архитектура шаблонизаторов BEMHTML и BEMTREE

Для обработки BEMTREE- и BEMHTML-шаблонов используется модуль [bem-xjst](https://ru.bem.info/tools/templating-engines/bemxjst/).
BEM-XJST является надмножеством [языка шаблонов XJST](https://github.com/veged/xjst), который, в свою очередь, является надмножеством JavaScript.

BEM-XJST — это набор БЭМ-ориентированных хелперов, расширяющий
стандартный XJST-синтаксис. В нем определены:

  * хелперы для записи подпредикатов, относящихся к предметной области БЭМ;
  * хелперы для определения подпредиката по моде;
  * хелперы для применения XJST-конструкций `apply` и `applyNext` по произвольной моде;
  * конструкцию [applyCtx](#applyctx).

BEM-XJST реализует наиболее общую схему обработки шаблонов. Логика, специфическая для каждого из шаблонизаторов в отдельности, реализована на уровне их **базовых шаблонов**.

Базовый шаблон – это реализация блока `i-bem` в технологии
 соответствующего шаблонизатора:

* для BEMTREE — [i-bem.bemtree](https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/i-bem.bemtree);
* для BEMHTML — [i-bem.bemhtml](https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/i-bem.bemhtml).

Базовый шаблон определяет:
* набор и порядок выполнения доступных для технологии стандартных [мод](#moda);
* [поля контекста](#context_field);

Можно выделить четыре уровня абстракции, на каждом из которых реализуется часть совокупной логики шаблонизатора:

1. XJST
2. BEM-XJST
3. Базовый шаблон
4. Пользовательский шаблон

Каждый последующий уровень использует  логику, реализованную на предыдущем и дополняет (переопределяет) ее:

* XJST предоставляет базовые конструкции для:
	* проверки истинности подпредикатов (`match`);
	* выполнения тела шаблона в модифицированном контексте (`local` и `apply`).
* BEM-XJST реализует:
	* логику, относящуюся к предметной области БЭМ – хелперы для записи подпредикатов для блоков, элементов, модификаторов;
	* логику для работы с фрагментом входного БЭМ-дерева (поле контекста `this.ctx`) и конструкцию `applyCtx`, предназначенную для его модификации;
	* возможность вызывать `apply`  по моде;
	* общую схему обработки шаблонов.
* Базовый шаблон реализует логику, специфическую для конкретной технологии:
	* набор стандартных мод;
	* поля контекста.

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

![levels](https://raw.githubusercontent.com/Murdalay/bem-core/feature_doc/common.docs/templating/template-levels.png)


<a name="bemx_intro"></a>
### Знакомство с BEM-XJST-шаблонизаторами

Как следствие использования описанной выше архитектуры, синтаксис BEMHTML и BEMTREE почти идентичен. Вся разница между ними заключается в:
* количестве доступных стандартных мод;
* нескольких полях контекста, специфических для каждого из шаблонизаторов.


Общие для BEMHTML и BEMTREE синтаксические конструкции и поля контекста объединены понятием **BEM-XJST-синтаксис**.

Шаблонизаторы, поддерживающие синтаксические конструкции и поля контекста, соответствующие BEM-XJST-синтаксису, называются **BEM-XJST-шаблонизаторами**.



<a name="bemx_basic"></a>
## Особенности BEM-XJST-шаблонизаторов

<a name="bem_area"></a>
### Привязка к БЭМ-предметной области

Шаблонизаторы BEMHTML и BEMTREE входят в связку технологических решений, обеспечивающих создание веб-интерфейсов в рамках
[БЭМ-методологии](https://ru.bem.info/method/).

Входные данные шаблонизатора — БЭМ-дерево в формате [BEMJSON](https://ru.bem.info/technology/bemjson/current/bemjson/), описывающее веб-страницу.
Языки шаблонов BEMHTML и BEMTREE предлагают специальные конструкции для обработки блоков, элементов и модификаторов.


<a name="decl_templatе"></a>

### Декларативные шаблоны

Ниже рассматриваются особенности декларативного подхода к созданию шаблонов на примере шаблонизатора BEMHTML.

Все эти особенности относятся и к шаблонизатору BEMTREE с той оговоркой, что результатом выполнения BEMTREE-шаблонов будет BEMJSON вместо HTML.


<a name="imperativ"></a>

#### Императивный подход

Традиционные шаблонизаторы предлагают **императивный подход** к написанию шаблонов: HTML формируется в процессе
последовательного чтения и выполнения шаблона.

<table>
<tr>
    <th>Входные данные</th>
    <th>Шаблон</th>
    <th>Результат</th>
</tr>
<tr>
    <td>
        <pre><code>
{
  items: [
    { text: '1' },
    { text: '2' }
  ]
}
        </code></pre>
    </td>

    <td>
        <pre><code>
&lt;ul class="menu"&gt;
    [% foreach item in items %]
        &lt;li class="menu&#95;&#95;item"&gt;
            [% item.text %]
        &lt;/li&gt;
    [% end %]
&lt;/ul&gt;
        </code></pre>
    </td>
    <td>
        <pre><code>
&lt;ul class="menu"&gt;
    &lt;li class="menu&#95;&#95;item">1&lt;/li&gt;
    &lt;li class="menu&#95;&#95;item">2&lt;/li&gt;
&lt;/ul&gt;
        </code></pre>
    </td>

</tr>
</table>

В таком шаблоне неизбежна избыточность, вызванная синтаксическими требованиями HTML: *вывести открывающий
тег — сгенерировать содержимое — вывести закрывающий тег*. Еще выше избыточность в таблицах, списках и т.п.


<a name="declarativ"></a>

#### Декларативный подход

**Декларативный подход** позволяет формулировать шаблоны как набор простых утверждений вида: *тип входных данных (БЭМ-сущность) — HTML-представление (тег, атрибут и т.п.)*.

<table>
    <tr>
        <th>Входные данные</th>
        <th>Шаблон</th>
        <th>Результат</th>
    </tr>
    <tr>
        <td>
        <pre><code>
{
    block: 'menu',
    content: [
        { elem: 'item', content: '1' },
        { elem: 'item', content: '2' }
    ]
}
        </code></pre>
        </td>
        <td>
        <pre><code>
block('menu')(
    tag()('ul'),
    elemMatch('item').tag()('li')
)
        </code></pre>
        </td>
        <td>
        <pre><code>
&lt;ul class="menu"&gt;
    &lt;li class="menu&#95;&#95;item"&gt;1&lt;/li&gt;
    &lt;li class="menu&#95;&#95;item"&gt;2&lt;/li&gt;
&lt;/ul&gt;
        </code></pre>
        </td>
    </tr>
</table>


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


<a name="language"></a>

### Язык описания и исполнения шаблонов — JavaScript

Шаблонизаторы BEMHTML и BEMTREE представляют собой специализированный язык (DSL), **расширяющий** JavaScript.

В шаблонах могут использоваться **любые** JavaScript-конструкции.

Перед выполнением шаблоны компилируется в оптимизированный JavaScript, который принимает BEMJSON и возвращает HTML для BEMHTML и BEMJSON для BEMTREE.

Такой шаблон может выполняться как на стороне сервера, так и на стороне клиента.


<a name="restrictions"></a>

### Ограничения на уровне соглашений

{'fraction_non_alphanumeric': 0.10696447612099444, 'fraction_numerical': 0.002693753858241203, 'mean_word_length': 4.518736450913596, 'pattern_counts': {'":': 0, '<': 167, '<?xml version=': 0, '>': 171, 'https://': 20, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '511800', 'n_tokens_mistral': 7587, 'n_tokens_neox': 8864, 'n_words': 1740}