<commit_before># Table of Contents

 - Компиляция
 - автоматический режим
 - ручной режим
 - RAD.template(templateString, [options])
 - опции шаблонов
 - открытые теги, закрытые теги
 - support custom tags & webcomponents, кастомные теги, порядок создания инркментал дома
 - работа со стороними библиотеками
 - кастомный рендеринг
 - работа с атрибутами, кастомные атрибуты, атрибуты без значений
 - выражения
 - undefined в выражениях
 - js в темплейтах, кавычки
 - контекст
 - key для сохранения элементов
 - статик масивы для экономии памяти
 - хелперы
  - стандартные хелперы
  - хелперы с сонтентом
  - контекст в хэлперах
  - передача данных с хэлперов оберток
 - refs
 - динамические refs
 - форматирование текста, html escape, utf коды

#Компиляция

Компиляция преобразует строку-шаблон в набор [IncrementalDOM](http://google.github.io/incremental-dom/#about) функций.

```ejs
<h1>Hello <%= data.name %>!</h1>
``` 

Результатом компиляции такой строки будет функция, выполняющая код аналогично следующей:

```javascript
var template = function(data) {
    elementOpen('h1');
    text('Hello ' + data.name);
    elementClose('h1');
};
```
> термин `аналогично` связан с тем что функции `elementOpen` `text` `elementClose` будут представлены в другом, укороченом, синтаксисе, определенном через замыкание. Так же возможны некоторые внутрение оптимизации синтаксиса, но функционально будет выполнена именно данная последовательность комманд.
> 
> Также обращаем Ваше внимание на то, что шаблон не обязательно должен иметь один родительский элемент

## Автоматическая и ручная компиляция шаболнов

Компиляция шаблона в `RAD` может происходить в автоматическом и ручном режиме.

### автоматический режим

В случае если вы устанавливаете значения свойства класса **View** `template` как строку, при инициализации экземпляра этого класса будет произведенна автоматическая компиляция в шаблонную функцию.

### ручная компиляция

Если вы хотите произвести компиляцию шаблона с кастомными параметрами или использовать уже заранее подготовленную шаблонную функцию, Вы можете так же присвоить ее в качестве значения свойству `template` необходимого класса.

> В этом случае, следует учитывать два момента:
> 
> - переданные во время компиляции опции остаються установленными и для последующих вызовов функции компиляции, поэтому в случае установки кастомных параметров не для всего проекта, после компиляции Вам необъодимо будет вернуть параметры по умолчанию
> - функция которая устанавливаеться в качестве значения параметра `template` должна манипулировать c элементами DOM'a с помощью функций [incremental-dom](). Если вам необходима другая функциональность смотрите [работа со стороними библиотеками]() и [кастомный рендеринг](). 

Для того чтобы скомпилировать шаблон в функцию необходимо воспользоваться методом [`RAD.template`](), например следующим образом:

```javascript
import template from 'RAD';

var templateFn = template(require('patch-to-template.ejs'));
```

В качестве второго параметра компиляции можно передавать  [опции компиляции]().

### RAD.template(templateString, [options])

Данная функция компилирует строку переданную первым параметром в шаблонную функцию c командами [incremental-dom]() 

```javascript
var container = document.getElementById('container');
var template = RAD.template('<h1>Hello <%= data.name %>!</h1>');

RAD.utils.IncrementalDOM.patch(container, template, {name: 'John'});
```

> Обратите внимание на то как применяеться шаблонная функция, на самом деле в большинстве случаев Вам [нет необходимости применять шаблоны в ручную](#). Но Вы всегда можете использовать как и прямую ссылку на `IncrementalDOM` если добавите библиотеку в проект, так уже внедренную `RAD.utils.IncrementalDOM`, разницы нет.

### options

Вторым параметром идут опции компиляции:

<table>
    <tbody>
    <tr>
        <th> Parameter</th>
        <th> Type</th>
        <th> Default</th>
        <th> Description</th>
    </tr>
    <tr>
        <th colspan="4"> Парсинг шаблонов </th>
    </tr>
    <tr>
        <td> template </td>
        <td> Object </td>
        <td>
			<pre>
{
	evaluate: /&lt;%([\s\S]+?)%&gt;/g,
	interpolate: /&lt;%=([\s\S]+?)%&gt;/g,
	escape: /&lt;%-([\s\S]+?)%&gt;/g
}
            </pre>
        </td>
        <td>
            По умолчанию шаблоны используют ERB-синтаксис такой же как и <a href="http://underscorejs.org/#template"> underscore.template</a>. Параметр template позволяет задавать свои символы для выражений (аналогично _.templateSettings в underscore).
        </td>
    </tr>
    <tr>
        <td> order </td>
        <td> String Array </td>
        <td> ['interpolate', 'escape', 'evaluate'] </td>
        <td>
            Определяет порядок применения регулярных вырожений из `options.template`, для случая если вы захотите пререопределить используемые шаблоны
        </td>
    </tr>
    <tr>
        <td> evaluate </td>
        <td> Object </td>
        <td>
      <pre>
{
    name: 'script',
    open: '&lt;script&gt;',
    close: '&lt;/script&gt;'
}
     </pre>
        </td>
        <td>
            Служебный тег для промежуточного преобразования во время компиляции в который преобразовуеться javascript код в ваших шаблонах, расположеный внутри <i>evaluate</i> regular expression. Вы можете использовать данные теги вместо evaluate expressions.
        </td>
    </tr>
    <tr>
        <td> accessory </td>
        <td> Object </td>
        <td>
      	<pre>
{
    open: '{%',
    close: '%}'
}
      	</pre>
</td>
        <td> Служебные префикс и суффикс указывающие на начало и конец вычисляемого значения в шаблоне, и используемые для промежуточного преобразования во время компиляции в который преобразовуеться выражения <i>interpolate</i> и <i>escape</i> из шаблона. Так же как и служебный тег настроенный в <i>evaluate</i>, вы можете использовать их на прямую. 
        <br><br>
        <i><b>Следует учитывать что служебные теги и префиксы имеют ограничения на синтаксис и разрешенные знаки, поэтому их прямое переопределение крайне не рекомендуеться - используйте настройки `template` для изменения синтаксиса шаблонов</b></i>
        </td>
    </tr>
    <tr>
        <td> emptyString </td>
        <td> Boolean </td>
        <td><b>true</b></td>
        <td> Опция которая указывает как будет отображен <i><b>undefined</b></i> в данных при рендеренге шаблонов. Если выставлено <i><b>true</b></i>, то вместо <i><b>undefined</b></i> будет отображена пустая строка. </td>
    </tr>
    <tr>
        <td> staticKey </td>
        <td> String </td>
        <td> 'key' </td>
        <td> Имя атрибута для назначения <a href="http://google.github.io/incremental-dom/#demos/using-keys">индивидуального ключа</a> конкретному элементу шаблона.</td>
    </tr>
    <tr>
        <td> staticArray </td>
        <td> String </td>
        <td> 'static-array' </td>
        <td> Имя атрибута для назначения <a href="http://google.github.io/incremental-dom/#rendering-dom/statics-array">имени массиву статических атрибутов элемента</a>.
        <br><br>
        <i>Обратите внимание что в случае использования одного и того же имени массива в разных элементах <b>одного шаблона</b> - массив будет одним и тем же. И он будет сформирован из всех атрибутов первого элемента в котором будет использованно данное имя. <br><br>
        В случае если в последующих элементах будет атрибуты будут иметь отличное значение от уже помещенного в массив, атрибут автоматически удаляеться из массива, но в пердидущие элементы не будет возвращен. Поэтому после определения массива статических атрибутов с помощью первого элемента, в последующих элементах просто используйте имя массива без всяких атрибутов.<i> </td>
    </tr>
    <tr>
        <td> nonStaticAttributes </td>
        <td> String Array </td>
        <td> ['id', 'name'] </td>
        <td> Список атрибутов элемента которые никогда не будут помещены в массив статических аттрибутов. </td>
    </tr>
    <tr>
        <td> textSaveTags </td>
        <td> String Array </td>
        <td> ['pre', 'code'] </td>
        <td> Имена тегов в которых не удаляються пробелы и переносы строк. </td>
    </tr>
    <tr>
        <td> voidRequireTags </td>
        <td> String Array </td>
        <td>
            ['input', 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']
        </td>
        <td> Самозакрывающиеся теги, которые будут представлены <a href="http://google.github.io/incremental-dom/#api/elementVoid">void</a>  коммандой.</td>
    </tr>
    <tr>
        <td> debug </td>
        <td> Boolean
        </td>
        <td><b>false</b>
        </td>
        <td> Опция развернутой компиляции шаблона, если установлена в <b>true</b> то шаблон компилируется в развернутом виде(более читабельном), который можно вывести через <pre>console.log(templateFn.toString());</pre> и посмотреть на валидность синтаксиса. <br><br>
        И кроме того, шаблонная функция оборачиваться в <i>try/catch</i> которая позволяте отображать тип ошибки и шаблон в котором произошла ошибка: <br><br>
        <img src="assets/error.png" /> </td>
    </tr>
    <tr>
        <th colspan="4"> Передача данных </th>
    </tr>
    <tr>
        <td> parameterName </td>
        <td> String </td>
        <td> 'data' </td>
        <td>
            Задает имя объекта в котором будут упакованны все данные переданные в функцию-шаблон: <br/>
            <pre>RAD.template('&lt;h1&gt;Hello &lt;%= data.name %&gt;!&lt;/h1&gt;')</pre>
        </td>
    </tr>
    <tr>
        <td> renderContentFnName </td>
        <td> String </td>
        <td> 'content' </td>
        <td> <b>Helpers:</b> Задает имя функции, которую можно использовать непосредственно в шаблоне хелперов для рендеринга вложенного контента(transclude helpers).
        <pre>
&lt;div class=&quot;my-class&quot;&gt;
	&lt;% content(); %&gt;
&lt;/div&gt;</pre>  </td>
    </tr>
    <tr>
        <td> parentParameterName </td>
        <td> String </td>
        <td> 'parent' </td>
        <td> <b>Helpers:</b> Задает имя объекта данных, которые передаються в функцию рендеренга контента и будут доступены в шаблоне, который использует данный хелпер (transclude helpers).
        <br><br>
        helper template example:
        <pre>
&lt;div class=&quot;x-div-class&quot;&gt;
	&lt;% content({id: 'smth'}); %&gt;
&lt;/div&gt;</pre>
			using data template example:
			<pre>
&lt;x-div&gt;
	&lt;x-input parent-id=&quot;&lt;%= parent.name %&gt;&quot;/&gt;
&lt;/x-div&gt;</pre>
<i>Стоит отметить, что не рекомендуеться передача данных таким способом, так как это "размазывает" логику по шаблонам, но документация составлена, так как такая возможность есть. </i>	
		 </td>
    </tr>
    <tr>
        <th colspan="4"> Форматирование текста </th>
    </tr>
    <tr>
        <td> BREAK_LINE </td>
        <td> Regular Expression </td>
        <td> /(\r\n|\n|\r)\s{0,}/gm </td>
        <td> Определяет регулярное выражение, с помощью которого убираються все переносы строк в шаблонах. Не требует переопределения. </td>
    </tr>
    <tr>
        <td> escape </td>
        <td> Regular Expression </td>
        <td> /(&amp;amp;|&amp;lt;|&amp;gt;|&amp;quot;)/g </td>
        <td> Определяет регулярное выражение для поиска с дальнейшей заменой <i>HTML Escape</i> последовательностей в шаблонах. Работает в связке с <i>options.MAP</i>. </td>
    </tr>
    <tr>
        <td> MAP </td>
        <td> Object </td>
        <td>
       	<pre>
{
    '&amp;amp;': '&amp;',
    '&amp;lt;': '&lt;',
    '&amp;gt;': '&gt;',
    '&amp;quot;': '&quot;'
}
      		</pre>
        </td>
        <td> Определяет набор соответствий последовательностей символов - непосредственно символам в тексте, оттображаемым через шаблонную функцию. Используеться как правило для замены символов в <i>HTML Escape</i> последовательностях. </td>
    </tr>

    <tr>
        <th colspan="4"> Компоненты </th>
    </tr>
    <tr>
        <td> components </td>
        <td> Object </td>
        <td> <b>null</b> </td>
        <td>Определяет локальные компоненты.
            <br>
            <br>
            RAD.js позволяет создавать реюзабельные компоненты которые дуступны внутри шаблонов посредством кастомных тегов. В качестве компонента может выступать как простая функция так и View.
            <br>
            <br>
            Компоненты могут быть как локальные так и глобальные.
            <br>
            <br>
            Глобальный компонент регистрируется при помощи метода <code>RAD.template.registerHelper</code> после чего становиться доступным для использования внутри любого шаблона.
            <br>

        </td>
    </tr>
    </tbody>
</table>

> Обратите внимание, что переданные во время компиляции опции остаються установленными и для последующих вызовов функции компиляции, поэтому в случае установки кастомных параметров не для всего проекта, после компиляции Вам необъодимо будет вернуть параметры по умолчанию

## открытые теги, закрытые теги
Все самозакрывающиеся теги желательно записывать в строгом синтаксисе, закрывая их:

```html
<img src="image.jpg" alt="image" /> 
```
Это позволит избежать возможных ошибок с неправильным парсингом шаблонов.

> Также следует помнить о том что в опциях компиляции шаблонов есть список тегов которые всегда будут представлены как [void](http://google.github.io/incremental-dom/#api/elementVoid) команда шаблонной функции.

## support custom tags & webcomponents, кастомные теги, порядок создания инркментал дома

Так как [incremental-dom](http://google.github.io/incremental-dom) оперирует непосредственно с реальной DOM структурой, то 
## работа со стороними библиотеками

## кастомный рендеринг
У вас есть возможность переопределить тип рендеринга для любой непосредственной View в вашем приложении. 
## работа с атрибутами, кастомные атрибуты, атрибуты без значений
### атрибуты элементов
### helpers attributes
## выражения
## undefined в выражениях
## js в темплейтах, кавычки, точка с запятой
## контекст рендеринга


### контекст Views

Рендеринг шаблона любой View происходит в ее контексте, это значит что вы в самом шаблоне можете в любой момент обратиться к **this** и выполнить любой метод вью или получить значение свойства экземпляра вашей View.

```ejs
<%
	/* обращение к любому свойству View */
	var criteria = this.criteria;
	/* выполнение любого метода экземпляра View */
	var data = this.filterData(criteria);
%>
<div><%= data %></div>
```

### helpers context

В том случае если вы используете хелперы в вашем шаблоне внутри них контекст сохраняеться. То есть **this** внутри функции хелпера сохраняеться как ссылка на View в шаблон которой вставлен хелпер.

> Несмотря на то что вы можете использовать контекст для передачи данных в хелпер, делать это не рекомендуеться. Так как может повлиять на возможность переиспользования кода и нарушает его проздачность. Крайне рекомендуеться передавать данные в хелпер через [атрибуты](). Например: 
> 
> ```ejs
> 	<x-sidemenu list="<%= this.menuContent %>" permission="<%= this.getUserPermission() %>" />
> ```
 
## атрибут `key` для сохранения элементов, работа со списками

Если вам необходимо быть уверенным в том что при рендеринге шаблона элемент не будет заменен, а ему будут добавлены новые свойтва или контент - вам необходимо указать key для этого элемента в шаблоне:

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
> Имя атрибута которым указываеться key элемента можно изменить с помощью [опций]() компиляции шаблонов.

Это особенно важно при работе со списками, например, в случае если вы добавите в массив данных элемент в начало массива, что бы diff алгоритм incremental-dom не поменял контент всех элементов списка, а корректно вставил элемент в [начало списка](http://google.github.io/incremental-dom/#demos/using-keys).

> Хотелось бы еще раз напомнить принцип работы инкрементал дома он начинает проверку сверху-вниз, и если находит несоответствие команды шаблонной функции к реальному дому то будут внесены изменения. Но это касаеться именно элементов или их атрибутов которые определяються. Поэтому если вы хотите соохранить какие либо стили которые добавлены сторонней библиотекой после рендеринга то вым не надо делать ничего, просто проследите что-бы в шаблоне эти стили не перезатерались. Более подробно можно почитать в разделе посвященном [работе со сторонними библиотеками]().

## статик масивы для экономии памяти
В incremental-dom существует [возможность](http://google.github.io/incremental-dom/#rendering-dom/statics-array) создания массива статических атрибутов для элемента. Вы можете ее использовать и в Ваших шаблонах. Для этого необходимо указать кастомный атрибут `static-array` в елементе шаблона, и имя массива в качестве значения атрибута.

```
<div static-array="divStaticAttrs" class="div-class line" style="border: 0;">
	...
</div>
...
<div static-array="divStaticAttrs">
	...
</div>
```

**Алгоритм формирования массива статических атрибутов для элемента** : При нахождении в элемента с атрибутом указывающим необходимость создания статического массива и именем массива которое ранее не использовалось в данном шаблоне, формируеться массив содержащий все атрибуты данного, первого элемента, которые являються статическими, то есть:

- атрибут не указан в опции компиляции `nonStaticAttributes`,
- в значении атрибута нет javascript выражений или вычеслений: `<%= ... %>`, `<%- ... %>` или `<% ... %>`.

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

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

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>" static-array="listItem" class="..." style="...">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
> В этом примере в массив статических атрибутов элемента будут добавлены `class` и `style`, это не только немного сэкономит память но и слегка увеличит быстродействие шаблона, так как изменения статических атребутов не отслеживаеться и incremental-dom может оптимизировать работу непосредственно с конкретным элементом.

Конечно вы можете использовать массивы статических атрибутов и для сокращения верстки, но мы рекомендуем их использовать только при генерации больших списков однотипных элементов, что бы не возникала путаница.

> - Если Вы не укажете имя массива статических атрибутов, то при компиляции шаблона это имя будет сгенерированно автоматически. Но в этом случае у Вас не будет возможности использовать данный массив повторно для других элементов.
> 
> ```ejs
> <div static-array class="div-class line" style="border: 0;">
>	...
> </div>
> ```
> 
> - Вы так же можете заменить имя атрибута которым указываеться static array элемента в [опциях]() компиляции шаблонов.
> - Всвязи с тем что значения атрибута являеться именем массива в javascript, то его синтаксис подчиняеться там же правилам что и наименование переменных в javascript.
> - область видимости данных массивов - это шаблон в котором указан элемент. То есть у вас есть возможность использовать массивы с одним и тем же именнем в разных шаблонах, и это будут разные массивы.


## хелперы
Глобальные компоненты с глобальной областью видимости. Отличие от компонентов(нет колбеков на жизненый цикл). Отличие от вьюх - когда они привязаны к логике приложения и моделям данных(кусок статьи о глупых и умных компонентах)

> Обратите внимание что атрибуты html елемента не переносяться на прямую на первый элемент хелпера, это надо делать вручную
> 
> Также обратите внимание что шаблон не должен иметь один родительский элемент


### передача данных в хелпер
Данные в хелпер рекомендуеться передовать как 
### стандартные хелперы
### хелперы с контентом
### контекст в хэлперах
### передача данных с хэлперов оберток
## refs
При компиляции шаблона есть возможность задать элементы DOM ссылки на которые вы хотите иметь ссылки в javascript без использования стороних бибиотек, например **jQuery**, или без дополнительного вызова методов DOM. Для этого вым необходимо в элемент, на который вам нужна ссылка в вашем View, в шаблоне добавить кастомный атрибут `ref` и его значение, например:

```ejs
...
<div class="panel" ref="container">
	...
</div>
...
```

В этом случае, сразу после первого рендеринга шаблона у вас будут прямые ссылки на элементы DOM в которых установлен `ref`, через `this.refs.{...}`. Где `this` это контекст экземпляра View. Ссылка на DOM элемент **div** из шаблона примера будет доступен в любом методе View, которой принадлежит данный шаблон, через `this.refs.container`.

Говоря коротко: после рендеринга все DOM элементы в которых указан атрибут `ref` будут доступны по прямой ссылке во View.

> Обратите внимание на следующие моменты:
> 
> - что  после каждого рендеринга обект `refs` как свойство View заменяеться а не модифицируеться. Поэтому вы можете свободно использовать любую ссылку на DOM через `this.refs.{...}` в своем коде, но не рекомендуеться манипулировать с самим обектом `refs`.
> - имя атрибута можно поменять через опции компиляции
> - если в значении атрибута в шаблоне будет указан знак `-`, например `my-container` то в javascript это значение будет преобразовано в соответствии с camelCase правилом в `myContainer`.

### динамические refs

Вы можете также использовать динамически сгенерированные имена ссылок, например следующим образом:

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>" ref="<%= 'item_' + listItem.id %>">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
В данном примере будут динамически сформированы ссылки на все элементы списка. А доступ к ним из javascript можно организовать например следующим образом:

```javascript
	var listItem = this.refs['item_'+index];
```

### пример использования refs в хелперах

Вы так же 

## форматирование текста, html escape, utf коды
## коментарии в шаблонах
Вы можете использовать два типа коментариев в ваших шаблонах

- первый: это стандартные коментарии html. Коментарии данного типа не отображаються и не переносяться в шаблонную функцию

```ejs
<!--This is a comment.-->
<div>
	...
</div>
```

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

```ejs
<% /* This is a comment.
* Another line of comment.
*/ %>
<div>
	...
</div>
```
> Необходимость закрытия javascript коментариев связана с тем что при переносе кода в шаблонную функцию переносы строк удаляються. И если коментарий не будет закрыт, функция станет синтексически не верной так как код функции после окончания станет частью коментария.

---
> Обратите внимание что компиляцию хелперов можно произвести с помощью `RAD.template` и с помощью `RAD.template.compileHelper`. Разница состоит в том что в первом случае хелпер функция будет скомпелированная с замыканием и у вас не будет прямого доступа к  второму аргументу функции, который используеться в качестве функции рендеринга transclude контента. Во втором случае при компиляции, у вас будет прямой доступ и это позволит вам более изящно и коротко писать код transclude helpers.
> 
> Например, код простейшего transclude helper'aбудет выглядеть следующим образом:
> 
> ``` ejs
> <div><% content(); %></div>
> ```
> 
> ```javascript
> var templateFn = RAD.template.compileHelper(require('./template.ejs'));
> RAD.template.registerHelper('my-custom-div', templateFn);
> ```<commit_msg>docs update<commit_after># Table of Contents

 - Компиляция
 - автоматический режим
 - ручной режим
 - RAD.template(templateString, [options])
 - опции шаблонов
 - открытые теги, закрытые теги
 - support custom tags & webcomponents, кастомные теги, порядок создания инркментал дома
 - работа со стороними библиотеками
 - кастомный рендеринг
 - работа с атрибутами, кастомные атрибуты, атрибуты без значений
 - выражения
 - undefined в выражениях
 - js в темплейтах, кавычки
 - контекст
 - key для сохранения элементов
 - статик масивы для экономии памяти
 - хелперы
  - стандартные хелперы
  - хелперы с сонтентом
  - контекст в хэлперах
  - передача данных с хэлперов оберток
 - refs
 - динамические refs
 - форматирование текста, html escape, utf коды

#Компиляция

Компиляция преобразует строку-шаблон в набор [IncrementalDOM](http://google.github.io/incremental-dom/#about) функций.

```ejs
<h1>Hello <%= data.name %>!</h1>
``` 

Результатом компиляции такой строки будет функция, выполняющая код аналогично следующей:

```javascript
var template = function(data) {
    elementOpen('h1');
    text('Hello ' + data.name);
    elementClose('h1');
};
```
> термин `аналогично` связан с тем что функции `elementOpen` `text` `elementClose` будут представлены в другом, укороченом, синтаксисе, определенном через замыкание. Так же возможны некоторые внутрение оптимизации синтаксиса, но функционально будет выполнена именно данная последовательность комманд.
> 
> Также обращаем Ваше внимание на то, что шаблон не обязательно должен иметь один родительский элемент

## Автоматическая и ручная компиляция шаболнов

Компиляция шаблона в `RAD` может происходить в автоматическом и ручном режиме.

### автоматический режим

В случае если вы устанавливаете значения свойства класса **View** `template` как строку, при инициализации экземпляра этого класса будет произведенна автоматическая компиляция в шаблонную функцию.

### ручная компиляция

Если вы хотите произвести компиляцию шаблона с кастомными параметрами или использовать уже заранее подготовленную шаблонную функцию, Вы можете так же присвоить ее в качестве значения свойству `template` необходимого класса.

> В этом случае, следует учитывать два момента:
> 
> - переданные во время компиляции опции остаються установленными и для последующих вызовов функции компиляции, поэтому в случае установки кастомных параметров не для всего проекта, после компиляции Вам необъодимо будет вернуть параметры по умолчанию
> - функция которая устанавливаеться в качестве значения параметра `template` должна манипулировать c элементами DOM'a с помощью функций [incremental-dom](). Если вам необходима другая функциональность смотрите [работа со стороними библиотеками]() и [кастомный рендеринг](). 

Для того чтобы скомпилировать шаблон в функцию необходимо воспользоваться методом [`RAD.template`](), например следующим образом:

```javascript
import template from 'RAD';

var templateFn = template(require('patch-to-template.ejs'));
```

В качестве второго параметра компиляции можно передавать  [опции компиляции]().

### RAD.template(templateString, [options])

Данная функция компилирует строку переданную первым параметром в шаблонную функцию c командами [incremental-dom]() 

```javascript
var container = document.getElementById('container');
var template = RAD.template('<h1>Hello <%= data.name %>!</h1>');

RAD.utils.IncrementalDOM.patch(container, template, {name: 'John'});
```

> Обратите внимание на то как применяеться шаблонная функция, на самом деле в большинстве случаев Вам [нет необходимости применять шаблоны в ручную](#). Но Вы всегда можете использовать как и прямую ссылку на `IncrementalDOM` если добавите библиотеку в проект, так уже внедренную `RAD.utils.IncrementalDOM`, разницы нет.

### options

Вторым параметром идут опции компиляции:

<table>
    <tbody>
    <tr>
        <th> Parameter</th>
        <th> Type</th>
        <th> Default</th>
        <th> Description</th>
    </tr>
    <tr>
        <th colspan="4"> Парсинг шаблонов </th>
    </tr>
    <tr>
        <td> template </td>
        <td> Object </td>
        <td>
			<pre>
{
	evaluate: /&lt;%([\s\S]+?)%&gt;/g,
	interpolate: /&lt;%=([\s\S]+?)%&gt;/g,
	escape: /&lt;%-([\s\S]+?)%&gt;/g
}
            </pre>
        </td>
        <td>
            По умолчанию шаблоны используют ERB-синтаксис такой же как и <a href="http://underscorejs.org/#template"> underscore.template</a>. Параметр template позволяет задавать свои символы для выражений (аналогично _.templateSettings в underscore).
        </td>
    </tr>
    <tr>
        <td> order </td>
        <td> String Array </td>
        <td> ['interpolate', 'escape', 'evaluate'] </td>
        <td>
            Определяет порядок применения регулярных вырожений из `options.template`, для случая если вы захотите пререопределить используемые шаблоны
        </td>
    </tr>
    <tr>
        <td> evaluate </td>
        <td> Object </td>
        <td>
      <pre>
{
    name: 'script',
    open: '&lt;script&gt;',
    close: '&lt;/script&gt;'
}
     </pre>
        </td>
        <td>
            Служебный тег для промежуточного преобразования во время компиляции в который преобразовуеться javascript код в ваших шаблонах, расположеный внутри <i>evaluate</i> regular expression. Вы можете использовать данные теги вместо evaluate expressions.
        </td>
    </tr>
    <tr>
        <td> accessory </td>
        <td> Object </td>
        <td>
      	<pre>
{
    open: '{%',
    close: '%}'
}
      	</pre>
</td>
        <td> Служебные префикс и суффикс указывающие на начало и конец вычисляемого значения в шаблоне, и используемые для промежуточного преобразования во время компиляции в который преобразовуеться выражения <i>interpolate</i> и <i>escape</i> из шаблона. Так же как и служебный тег настроенный в <i>evaluate</i>, вы можете использовать их на прямую. 
        <br><br>
        <i><b>Следует учитывать что служебные теги и префиксы имеют ограничения на синтаксис и разрешенные знаки, поэтому их прямое переопределение крайне не рекомендуеться - используйте настройки `template` для изменения синтаксиса шаблонов</b></i>
        </td>
    </tr>
    <tr>
        <td> emptyString </td>
        <td> Boolean </td>
        <td><b>true</b></td>
        <td> Опция которая указывает как будет отображен <i><b>undefined</b></i> в данных при рендеренге шаблонов. Если выставлено <i><b>true</b></i>, то вместо <i><b>undefined</b></i> будет отображена пустая строка. </td>
    </tr>
    <tr>
        <td> staticKey </td>
        <td> String </td>
        <td> 'key' </td>
        <td> Имя атрибута для назначения <a href="http://google.github.io/incremental-dom/#demos/using-keys">индивидуального ключа</a> конкретному элементу шаблона.</td>
    </tr>
    <tr>
        <td> staticArray </td>
        <td> String </td>
        <td> 'static-array' </td>
        <td> Имя атрибута для назначения <a href="http://google.github.io/incremental-dom/#rendering-dom/statics-array">имени массиву статических атрибутов элемента</a>.
        <br><br>
        <i>Обратите внимание что в случае использования одного и того же имени массива в разных элементах <b>одного шаблона</b> - массив будет одним и тем же. И он будет сформирован из всех атрибутов первого элемента в котором будет использованно данное имя. <br><br>
        В случае если в последующих элементах будет атрибуты будут иметь отличное значение от уже помещенного в массив, атрибут автоматически удаляеться из массива, но в пердидущие элементы не будет возвращен. Поэтому после определения массива статических атрибутов с помощью первого элемента, в последующих элементах просто используйте имя массива без всяких атрибутов.<i> </td>
    </tr>
    <tr>
        <td> nonStaticAttributes </td>
        <td> String Array </td>
        <td> ['id', 'name'] </td>
        <td> Список атрибутов элемента которые никогда не будут помещены в массив статических аттрибутов. </td>
    </tr>
    <tr>
        <td> textSaveTags </td>
        <td> String Array </td>
        <td> ['pre', 'code'] </td>
        <td> Имена тегов в которых не удаляються пробелы и переносы строк. </td>
    </tr>
    <tr>
        <td> voidRequireTags </td>
        <td> String Array </td>
        <td>
            ['input', 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']
        </td>
        <td> Самозакрывающиеся теги, которые будут представлены <a href="http://google.github.io/incremental-dom/#api/elementVoid">void</a>  коммандой.</td>
    </tr>
    <tr>
        <td> debug </td>
        <td> Boolean
        </td>
        <td><b>false</b>
        </td>
        <td> Опция развернутой компиляции шаблона, если установлена в <b>true</b> то шаблон компилируется в развернутом виде(более читабельном), который можно вывести через <pre>console.log(templateFn.toString());</pre> и посмотреть на валидность синтаксиса. <br><br>
        И кроме того, шаблонная функция оборачиваться в <i>try/catch</i> которая позволяте отображать тип ошибки и шаблон в котором произошла ошибка: <br><br>
        <img src="assets/error.png" /> </td>
    </tr>
    <tr>
        <th colspan="4"> Передача данных </th>
    </tr>
    <tr>
        <td> parameterName </td>
        <td> String </td>
        <td> 'data' </td>
        <td>
            Задает имя объекта в котором будут упакованны все данные переданные в функцию-шаблон: <br/>
            <pre>RAD.template('&lt;h1&gt;Hello &lt;%= data.name %&gt;!&lt;/h1&gt;')</pre>
        </td>
    </tr>
    <tr>
        <td> renderContentFnName </td>
        <td> String </td>
        <td> 'content' </td>
        <td> <b>Helpers:</b> Задает имя функции, которую можно использовать непосредственно в шаблоне хелперов для рендеринга вложенного контента(transclude helpers).
        <pre>
&lt;div class=&quot;my-class&quot;&gt;
	&lt;% content(); %&gt;
&lt;/div&gt;</pre>  </td>
    </tr>
    <tr>
        <td> parentParameterName </td>
        <td> String </td>
        <td> 'parent' </td>
        <td> <b>Helpers:</b> Задает имя объекта данных, которые передаються в функцию рендеренга контента и будут доступены в шаблоне, который использует данный хелпер (transclude helpers).
        <br><br>
        helper template example:
        <pre>
&lt;div class=&quot;x-div-class&quot;&gt;
	&lt;% content({id: 'smth'}); %&gt;
&lt;/div&gt;</pre>
			using data template example:
			<pre>
&lt;x-div&gt;
	&lt;x-input parent-id=&quot;&lt;%= parent.name %&gt;&quot;/&gt;
&lt;/x-div&gt;</pre>
<i>Стоит отметить, что не рекомендуеться передача данных таким способом, так как это "размазывает" логику по шаблонам, но документация составлена, так как такая возможность есть. </i>	
		 </td>
    </tr>
    <tr>
        <th colspan="4"> Форматирование текста </th>
    </tr>
    <tr>
        <td> BREAK_LINE </td>
        <td> Regular Expression </td>
        <td> /(\r\n|\n|\r)\s{0,}/gm </td>
        <td> Определяет регулярное выражение, с помощью которого убираються все переносы строк в шаблонах. Не требует переопределения. </td>
    </tr>
    <tr>
        <td> escape </td>
        <td> Regular Expression </td>
        <td> /(&amp;amp;|&amp;lt;|&amp;gt;|&amp;quot;)/g </td>
        <td> Определяет регулярное выражение для поиска с дальнейшей заменой <i>HTML Escape</i> последовательностей в шаблонах. Работает в связке с <i>options.MAP</i>. </td>
    </tr>
    <tr>
        <td> MAP </td>
        <td> Object </td>
        <td>
       	<pre>
{
    '&amp;amp;': '&amp;',
    '&amp;lt;': '&lt;',
    '&amp;gt;': '&gt;',
    '&amp;quot;': '&quot;'
}
      		</pre>
        </td>
        <td> Определяет набор соответствий последовательностей символов - непосредственно символам в тексте, оттображаемым через шаблонную функцию. Используеться как правило для замены символов в <i>HTML Escape</i> последовательностях. </td>
    </tr>

    <tr>
        <th colspan="4"> Компоненты </th>
    </tr>
    <tr>
        <td> components </td>
        <td> Object </td>
        <td> <b>null</b> </td>
        <td>Определяет локальные компоненты.
            <br>
            <br>
            RAD.js позволяет создавать реюзабельные компоненты которые дуступны внутри шаблонов посредством кастомных тегов. В качестве компонента может выступать как простая функция так и View.
            <br>
            <br>
            Компоненты могут быть как локальные так и глобальные.
            <br>
            <br>
            Глобальный компонент регистрируется при помощи метода <code>RAD.template.registerHelper</code> после чего становиться доступным для использования внутри любого шаблона.
            <br>

        </td>
    </tr>
    </tbody>
</table>

> Обратите внимание, что переданные во время компиляции опции остаються установленными и для последующих вызовов функции компиляции, поэтому в случае установки кастомных параметров не для всего проекта, после компиляции Вам необъодимо будет вернуть параметры по умолчанию

## открытые теги, закрытые теги
Все самозакрывающиеся теги желательно записывать в строгом синтаксисе, закрывая их:

```html
<img src="image.jpg" alt="image" /> 
```
Это позволит избежать возможных ошибок с неправильным парсингом шаблонов.

> Также следует помнить о том что в опциях компиляции шаблонов есть список тегов которые всегда будут представлены как [void](http://google.github.io/incremental-dom/#api/elementVoid) команда шаблонной функции.

## support custom tags & webcomponents, кастомные теги, порядок создания инркментал дома

Так как [incremental-dom](http://google.github.io/incremental-dom) оперирует непосредственно с реальной DOM структурой, то 
## работа со стороними библиотеками

## кастомный рендеринг
У вас есть возможность переопределить тип рендеринга для любой непосредственной View в вашем приложении. 
## работа с атрибутами, кастомные атрибуты, атрибуты без значений
### атрибуты элементов
### helpers attributes
## выражения
## undefined в выражениях
## js в темплейтах, кавычки, точка с запятой
## контекст рендеринга


### контекст Views

Рендеринг шаблона любой View происходит в ее контексте, это значит что вы в самом шаблоне можете в любой момент обратиться к **this** и выполнить любой метод вью или получить значение свойства экземпляра вашей View.

```ejs
<%
	/* обращение к любому свойству View */
	var criteria = this.criteria;
	/* выполнение любого метода экземпляра View */
	var data = this.filterData(criteria);
%>
<div><%= data %></div>
```

### helpers context

В том случае если вы используете хелперы в вашем шаблоне внутри них контекст сохраняеться. То есть **this** внутри функции хелпера сохраняеться как ссылка на View в шаблон которой вставлен хелпер.

> Несмотря на то что вы можете использовать контекст для передачи данных в хелпер, делать это не рекомендуеться. Так как может повлиять на возможность переиспользования кода и нарушает его проздачность. Крайне рекомендуеться передавать данные в хелпер через [атрибуты](). Например: 
> 
> ```ejs
> 	<x-sidemenu list="<%= this.menuContent %>" permission="<%= this.getUserPermission() %>" />
> ```
 
## атрибут `key` для сохранения элементов, работа со списками

Если вам необходимо быть уверенным в том что при рендеринге шаблона элемент не будет заменен, а ему будут добавлены новые свойтва или контент - вам необходимо указать key для этого элемента в шаблоне:

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
> Имя атрибута которым указываеться key элемента можно изменить с помощью [опций]() компиляции шаблонов.

Это особенно важно при работе со списками, например, в случае если вы добавите в массив данных элемент в начало массива, что бы diff алгоритм incremental-dom не поменял контент всех элементов списка, а корректно вставил элемент в [начало списка](http://google.github.io/incremental-dom/#demos/using-keys).

> Хотелось бы еще раз напомнить принцип работы инкрементал дома он начинает проверку сверху-вниз, и если находит несоответствие команды шаблонной функции к реальному дому то будут внесены изменения. Но это касаеться именно элементов или их атрибутов которые определяються. Поэтому если вы хотите соохранить какие либо стили которые добавлены сторонней библиотекой после рендеринга то вым не надо делать ничего, просто проследите что-бы в шаблоне эти стили не перезатерались. Более подробно можно почитать в разделе посвященном [работе со сторонними библиотеками]().

## статик масивы для экономии памяти
В incremental-dom существует [возможность](http://google.github.io/incremental-dom/#rendering-dom/statics-array) создания массива статических атрибутов для элемента. Вы можете ее использовать и в Ваших шаблонах. Для этого необходимо указать кастомный атрибут `static-array` в елементе шаблона, и имя массива в качестве значения атрибута.

```
<div static-array="divStaticAttrs" class="div-class line" style="border: 0;">
	...
</div>
...
<div static-array="divStaticAttrs">
	...
</div>
```

**Алгоритм формирования массива статических атрибутов для элемента** : При нахождении в элемента с атрибутом указывающим необходимость создания статического массива и именем массива которое ранее не использовалось в данном шаблоне, формируеться массив содержащий все атрибуты данного, первого элемента, которые являються статическими, то есть:

- атрибут не указан в опции компиляции `nonStaticAttributes`,
- в значении атрибута нет javascript выражений или вычеслений: `<%= ... %>`, `<%- ... %>` или `<% ... %>`.

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

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

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>" static-array="listItem" class="..." style="...">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
> В этом примере в массив статических атрибутов элемента будут добавлены `class` и `style`, это не только немного сэкономит память но и слегка увеличит быстродействие шаблона, так как изменения статических атребутов не отслеживаеться и incremental-dom может оптимизировать работу непосредственно с конкретным элементом.

Конечно вы можете использовать массивы статических атрибутов и для сокращения верстки, но мы рекомендуем их использовать только при генерации больших списков однотипных элементов, что бы не возникала путаница.

> - Если Вы не укажете имя массива статических атрибутов, то при компиляции шаблона это имя будет сгенерированно автоматически. Но в этом случае у Вас не будет возможности использовать данный массив повторно для других элементов.
> 
> ```ejs
> <div static-array class="div-class line" style="border: 0;">
>	...
> </div>
> ```
> 
> - Вы так же можете заменить имя атрибута которым указываеться static array элемента в [опциях]() компиляции шаблонов.
> - Всвязи с тем что значения атрибута являеться именем массива в javascript, то его синтаксис подчиняеться там же правилам что и наименование переменных в javascript.
> - область видимости данных массивов - это шаблон в котором указан элемент. То есть у вас есть возможность использовать массивы с одним и тем же именнем в разных шаблонах, и это будут разные массивы.


## хелперы
Глобальные компоненты с глобальной областью видимости. Отличие от компонентов(нет колбеков на жизненый цикл). Отличие от вьюх - когда они привязаны к логике приложения и моделям данных(кусок статьи о глупых и умных компонентах)

> Обратите внимание что атрибуты html елемента не переносяться на прямую на первый элемент хелпера, это надо делать вручную
> 
> Также обратите внимание что шаблон не должен иметь один родительский элемент

> Обратите внимание что компиляцию хелперов можно произвести с помощью `RAD.template` и с помощью `RAD.template.compileHelper`. Разница состоит в том что в первом случае хелпер функция будет скомпелированная с замыканием и у вас не будет прямого доступа к  второму аргументу функции, который используеться в качестве функции рендеринга transclude контента. Во втором случае при компиляции, у вас будет прямой доступ и это позволит вам более изящно и коротко писать код transclude helpers.
> 
> Например, код простейшего transclude helper'aбудет выглядеть следующим образом:
> 
> ``` ejs
> <div><% content(); %></div>
> ```
> 
> ```javascript
> var templateFn = RAD.template.compileHelper(require('./template.ejs'));
> RAD.template.registerHelper('my-custom-div', templateFn);
> ```

### передача данных в хелпер
Данные в хелпер рекомендуеться передовать как 
### стандартные хелперы
### хелперы с контентом
### контекст в хэлперах
### передача данных с хэлперов оберток
## refs
При компиляции шаблона есть возможность задать элементы DOM ссылки на которые вы хотите иметь ссылки в javascript без использования стороних бибиотек, например **jQuery**, или без дополнительного вызова методов DOM. Для этого вым необходимо в элемент, на который вам нужна ссылка в вашем View, в шаблоне добавить кастомный атрибут `ref` и его значение, например:

```ejs
...
<div class="panel" ref="container">
	...
</div>
...
```

В этом случае, сразу после первого рендеринга шаблона у вас будут прямые ссылки на элементы DOM в которых установлен `ref`, через `this.refs.{...}`. Где `this` это контекст экземпляра View. Ссылка на DOM элемент **div** из шаблона примера будет доступен в любом методе View, которой принадлежит данный шаблон, через `this.refs.container`.

Говоря коротко: после рендеринга все DOM элементы в которых указан атрибут `ref` будут доступны по прямой ссылке во View.

> Обратите внимание на следующие моменты:
> 
> - что  после каждого рендеринга обект `refs` как свойство View заменяеться а не модифицируеться. Поэтому вы можете свободно использовать любую ссылку на DOM через `this.refs.{...}` в своем коде, но не рекомендуеться манипулировать с самим обектом `refs`.
> - имя атрибута можно поменять через опции компиляции
> - если в значении атрибута в шаблоне будет указан знак `-`, например `my-container` то в javascript это значение будет преобразовано в соответствии с camelCase правилом в `myContainer`.

### динамические refs

Вы можете также использовать динамически сгенерированные имена ссылок, например следующим образом:

```ejs
<ul>
    <%  data.listItems.forEach(function(listItem) { %>
    <li key="<%= 'item_' + listItem.id %>" ref="<%= 'item_' + listItem.id %>">
        <%= listItem.name %>
    </li>
    <%  }); %>
</ul>
```
В данном примере будут динамически сформированы ссылки на все элементы списка. А доступ к ним из javascript можно организовать например следующим образом:

```javascript
	var listItem = this.refs['item_'+index];
```

### пример использования refs в хелперах

Шаблонах для хелперов вы так же можете использовать `ref` для того чтобы получить прямую ссылку на DOM элемент в javascript.

```ejs
<div ref="container">
	...
</div>
```

```javascript
import {template} from 'RAD'

var templateFn = template.compileHelper(require('./template.ejs'));

template.registerHelper('x-element', function (data, content) {
    // render template
    var refs = template(data, content);

    // attach logic to refs
    ...
});
```

## форматирование текста, html escape, utf коды

Для форматирования текста в исполняемом коде предусмотрены следующие возможности:

- Если вам необходимо использовать форматирование текста вы можете указать в опциях компиляции шаблона те теги для которых компилятор будет сохранять форматирование текста, то есть не удалять переносы строк и граничные пробелы. По умолчанию это теги `<pre>` и `<code>`.
- В случае необходимости вы всегда можете использовать UTF коды необходимых символов вида: `&#XXXX;`, где *XXXX* код символа который вы вставляете.
- И наконец вы можете использовать HTML escape последовательности, но в этом случае вам необходимо указать исходную и конечную последовательность символов в опуиях компиляции.

> Никто не мешает вам указать не HTML escape последовательность в качестве исходной и всего один символ в качестве конечной последовательности. Это могут быть любые последовательности символов, которые будут вставлены в `textContent` вашего элемента.

## коментарии в шаблонах
Вы можете использовать два типа коментариев в ваших шаблонах

- первый: это стандартные коментарии html. Коментарии данного типа не отображаються и не переносяться в шаблонную функцию

```ejs
<!--This is a comment.-->
<div>
	...
</div>
```

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

```ejs
<% /* This is a comment.
* Another line of comment.
*/ %>
<div>
	...
</div>
```
> Необходимость закрытия javascript коментариев связана с тем что при переносе кода в шаблонную функцию переносы строк удаляються. И если коментарий не будет закрыт, функция станет синтексически не верной так как код функции после окончания станет частью коментария.
{'fraction_non_alphanumeric': 0.10319044902615923, 'fraction_numerical': 0.0006111971314481298, 'mean_word_length': 3.787379303618453, 'pattern_counts': {'":': 0, '<': 743, '<?xml version=': 0, '>': 844, 'https://': 0, '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': '4016717', 'n_tokens_mistral': 18941, 'n_tokens_neox': 21814, 'n_words': 5505}