Skip to content

Commit

Permalink
Compiler.generate: support YModules, CommonJS and third party depende…
Browse files Browse the repository at this point in the history
…ncies (#375 fix)
  • Loading branch information
miripiruni committed Mar 20, 2017
1 parent bbafe2c commit b20bb52
Show file tree
Hide file tree
Showing 5 changed files with 528 additions and 106 deletions.
139 changes: 105 additions & 34 deletions docs/en/3-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
- [Optional End Tags](#optional-end-tags)
- [Unquoted attributes](#unquoted-attributes)
- [Escaping](#escaping)
- [Extending BEMContext](#extending-bemcontext)
- [Runtime linting](#runtime-linting)
- [Production mode](#production-mode)
* [Using thirdparty libraries](#using-thirdparty-libraries)
* [Extending BEMContext](#extending-bemcontext)
* [Bundling](#bundling)

## Choosing an engine, compiling and applying templates
Expand Down Expand Up @@ -347,39 +348,6 @@ In this case `content.html` will be rendered as is:

Notice that in `content.html` expected only string type.

### Extending BEMContext

You can extend `BEMContext` in order to use user-defined functions in the template body.

```js
var bemxjst = require('bem-xjst');
var templates = bemxjst.bemhtml.compile('');

// Extend the context prototype
templates.BEMContext.prototype.hi = function(name) {
return 'Hello, ' + name;
};

// Add templates
templates.compile(function() {
block('b').content()(function() {
return this.hi('templates');
});
});

// Input data
var bemjson = { block: 'b' };

// Apply templates
var html = templates.apply(bemjson);
```

The resulting `html` contains the string:

```html
<div class="b">Hello, templates</div>
```

### Runtime linting

By turning on `runtimeLint` option you can get warnings about wrong
Expand Down Expand Up @@ -456,6 +424,109 @@ $ cat stderr.txt
BEMXJST ERROR: cannot render block b1, elem undefined, mods {}, elemMods {} [TypeError: Cannot read property 'undef' of undefined]
```

### Using thirdparty libraries

BEMTREE and BEMHTML allows you using thirdparty libraries as well as a global
dependencies and different modular systems.

For example:

```js
{
requires: {
'lib-name': {
globals: 'libName', // Variable name from global scope
ym: 'lib-name', // Module name from YModules
commonJS: 'path/to/lib-name' // path to CommonJS library
}
}
}
```

`lib-name` module will be accessible in templates body like this:

```js
block('button').content()(function () {
var lib = this.require('lib-name');

return lib.hello();
});
```

It’s necessary to specify each environment you want to expose library to.

E.g. if you specify just global scope the library will only be available as global variable even though some module system will be present in runtime.

```js
{
requires: {
'lib-name': {
globals: 'dependName' // Variable name from global scope
}
}
}
```

Example of using `moment.js` library:

You don’t need to to provide path to module:

```js
{
requires: {
moment: {
commonJS: 'moment', // path to CommonJS module, relative bundle file
}
}
}
```

In templates body the module will be acessible as `this.require('moment')`.
You can use the template in any browser or in `Node.js`:

```js
block('post').elem('data').content()(function() {
var moment = this.require('moment');

return moment(this.ctx.date) // Time in ms from server
.format('YYYY-MM-DD HH:mm:ss');
});
```


### Extending BEMContext

You can extend `BEMContext` in order to use user-defined functions in the template body.

```js
var bemxjst = require('bem-xjst');
var templates = bemxjst.bemhtml.compile('');

// Extend the context prototype
templates.BEMContext.prototype.hi = function(name) {
return 'Hello, ' + name;
};

// Add templates
templates.compile(function() {
block('b').content()(function() {
return this.hi('templates');
});
});

// Input data
var bemjson = { block: 'b' };

// Apply templates
var html = templates.apply(bemjson);
```

The resulting `html` contains the string:

```html
<div class="b">Hello, templates</div>
```


## Bundling

Expand Down
141 changes: 107 additions & 34 deletions docs/ru/3-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
- [Опциональные закрывающие теги](#Опциональные-закрывающие-теги)
- [Атрибуты без кавычек](#Атрибуты-без-кавычек)
- [Экранирование](#Экранирование)
- [Расширение BEMContext](#Расширение-bemcontext)
- [Runtime проверки ошибок в шаблонах и входных данных](#runtime-проверки-ошибок-в-шаблонах-и-входных-данных)
- [Режим production](#Режим-production)
* [Подключение сторонних библиотек](#Подключение-сторонних-библиотек)
* [Расширение BEMContext](#Расширение-bemcontext)
* [Создание бандла](#Создание-бандла)

## Выбор движка, компиляция и применение шаблонов
Expand Down Expand Up @@ -341,39 +342,6 @@ var html = templates.apply(bemjson);

Обратите внимание, что в `content.html` ожидается именно строка.

### Расширение BEMContext

Вы можете расширять `BEMContext`, чтобы использовать в теле шаблона пользовательские функции.

```js
var bemxjst = require('bem-xjst');
var templates = bemxjst.bemhtml.compile('');

// Расширяем прототип контекста
templates.BEMContext.prototype.hi = function(name) {
return 'Hello, ' + name;
};

// Добавляем шаблоны
templates.compile(function() {
block('b').content()(function() {
return this.hi('templates');
});
});

// Входные данные
var bemjson = { block: 'b' };

// Применяем шаблоны
var html = templates.apply(bemjson);
```

В результате `html` будет содержать строку:

```html
<div class="b">Hello, templates</div>
```

### Runtime проверки ошибок в шаблонах и входных данных

Включив опцию `runtimeLint` вы можете отслеживать предупреждения о неправильных шаблонах и входных данных.
Expand Down Expand Up @@ -451,6 +419,111 @@ BEMXJST ERROR: cannot render block b1, elem undefined, mods {}, elemMods {} [Typ
```


## Подключение сторонних библиотек

Технологии [BEMTREE](api.ru.md#bemtree) и [BEMHTML](api.ru.md#bemhtml) поддерживают возможность подключения сторонних библиотек как глобально, так и для разных модульных систем с помощью опции [requires](api.ru.md#requires).

Для подключения укажите название библиотеки и в зависимости от используемой модульной системы:

* имя глобальной переменной;
* имя модуля из YModules;
* путь к модулю для CommonJS.

```js
{
requires: {
'lib-name': {
globals: 'libName', // Название переменной в глобальной видимости
ym: 'lib-name', // Имя модуля из YModules
commonJS: 'path/to/lib-name' // Путь к модулю CommonJS относительно собираемого файла
}
}
}
```

В шаблонах модули будут доступны с помощью метода `this.require`, например:

```js
block('button').content()(function () {
var lib = this.require('lib-name');

return lib.hello();
});
```

Не обязательно указывать все модульные системы для подключения библиотеки.

Например, можно указать зависимости глобально. В этом случае модуль всегда будет передаваться из глобальной переменной, даже если в среде исполнения будет модульная система.

```js
{
requires: {
'lib-name': {
globals: 'dependName' // Название переменной в глобальной видимости
}
}
}
```

**Пример подключения библиотеки `moment`**

Указывается путь к модулю:

```js
{
requires: {
moment: {
commonJS: 'moment', // Путь к модулю CommonJS относительно собираемого файла
}
}
}
```

В шаблонах модуль будет доступен с помощью метода `this.require('moment')`. Код шаблона пишется один раз, одинаково для исполнения в браузере и в `Node.js`:

```js
block('post').elem('data').content()(function() {
var moment = this.require('moment'); // Библиотека `moment`

return moment(this.ctx.date) // Время в ms, полученное с сервера
.format('YYYY-MM-DD HH:mm:ss');
});
```


### Расширение BEMContext

Вы можете расширять `BEMContext`, чтобы использовать в теле шаблона пользовательские функции.

```js
var bemxjst = require('bem-xjst');
var templates = bemxjst.bemhtml.compile('');

// Расширяем прототип контекста
templates.BEMContext.prototype.hi = function(name) {
return 'Hello, ' + name;
};

// Добавляем шаблоны
templates.compile(function() {
block('b').content()(function() {
return this.hi('templates');
});
});

// Входные данные
var bemjson = { block: 'b' };

// Применяем шаблоны
var html = templates.apply(bemjson);
```

В результате `html` будет содержать строку:

```html
<div class="b">Hello, templates</div>
```

## Создание бандла

Метод `generate` генерирует JS-код, который может быть передан и выполнен в браузере для получения объекта `templates`.
Expand Down
Loading

0 comments on commit b20bb52

Please sign in to comment.