From 8ef60a1cd6852dc554fd5a8ca39f2c5e586ede4d Mon Sep 17 00:00:00 2001 From: Inna Belaya Date: Tue, 18 Aug 2015 23:20:16 +0300 Subject: [PATCH] new description added --- README.md | 449 ++++++++++++++++++++++++++++++++++++++++++++++++------ api.ru.md | 205 +++++++++++++++++++++++++ 2 files changed, 610 insertions(+), 44 deletions(-) create mode 100644 api.ru.md diff --git a/README.md b/README.md index e247b62..1a36138 100644 --- a/README.md +++ b/README.md @@ -1,87 +1,448 @@ enb-bem-i18n ============ - [![NPM version](http://img.shields.io/npm/v/enb-bem-i18n.svg?style=flat)](https://www.npmjs.org/package/enb-bem-i18n) [![Build Status](http://img.shields.io/travis/enb-bem/enb-bem-i18n/master.svg?style=flat&label=tests)](https://travis-ci.org/enb-bem/enb-bem-i18n) [![Build status](https://img.shields.io/appveyor/ci/blond/enb-bh.svg?style=flat&label=windows)](https://ci.appveyor.com/project/blond/enb-bh) [![Coverage Status](https://img.shields.io/coveralls/enb-bem/enb-bem-i18n.svg?style=flat)](https://coveralls.io/r/enb-bem/enb-bem-i18n?branch=master) [![devDependency Status](http://img.shields.io/david/enb-bem/enb-bem-i18n.svg?style=flat)](https://david-dm.org/enb-bem/enb-bem-i18n) -Поддержка `BEM.I18N` для ENB. +Пакет предоставляет набор ENB-технологий для сборки файлов, обеспечивающих мультиязыковую поддержку проектов, созданных по [БЭМ-методологии](https://ru.bem.info/method/). Под мультиязыковой поддержкой понимается интернационализация (далее по тектсу также i18n). + +С помощью технологий пакета `enb-bem-i18n` осуществляется сборка модуля для интернационализации (`i18n`). + +**Технологии пакета `enb-bem-i18n`:** + +* [keysets](/api.ru.md#keysets) — служебная технология для сборки исходных файлов с переводами. +* [i18n](/api.ru.md#i18n) — технология для формирования бандлов с переводами для каждого языка, которые будут использоваться в дальнейшем. +* [i18n-keysets-xml](/api.ru.md#i18n-keysets-xml) — технология для локализации сервисов, использующих XSLT для шаблонизации. + +Принципы работы технологий и их API описаны в документе [API технологий](/api.ru.md). + +**Совместимость:** пакет поддерживает следующие библиотеки: + +* [bem-bl](https://ru.bem.info/libs/bem-bl/dev/) +* [bem-core](https://ru.bem.info/libs/bem-core/) -Установка: ----------- +>Особенности реализации для каждой библиотеки описаны в разделе [подключение библиотек](#Поддержка-библиотек). +## Установка + +Установите пакет `enb-bem-i18n`: ``` npm install --save-dev enb-bem-i18n ``` -Для работы модуля требуется зависимость от пакета `enb` версии `0.11.0` или выше. +**Требования:** зависимость от пакета `enb` версии `0.11.0` или выше. + +## Обзор документа + + +- [Быстрый старт](#Быстрый-старт) +- [Основные понятия](#Основные-понятия) + - [Исходные данные — keysets](#Исходные-данные--keysets) + - [Расположение в файловой системе](#Расположение-в-файловой-системе) + - [Ядро `i18n`](#Ядро-i18n) +- [Работа с технологиями](#Работа-с-технологиями) + - [Объединение данных](#Объединение-данных) + - [Обработка данных](#Обработка-данных) +- [Использование](#Использование) + - [В JavaScript](#В-javascript) + - [Использование в Node.js](#Использование-в-nodejs) + - [Использование в браузере](#Использование-в-браузере) + - [В шаблонах](#В-шаблонах) +- [API `i18n`](#api-i18n) + - [Инициализация](#Инициализация) + - [Параметризация значений](#Параметризация-значений) +- [Отличия в работе](#Отличия-в-работе) + - [Переключение между языками во время исполнения](#Переключение-между-языками-во-время-исполнения) + - [Хранение общих keysets-файлов с переводами](#Хранение-общих-keysets-файлов-с-переводами) + - [Расположение ядра `i18n`](#Расположение-ядра-i18n) + + -Технологии ----------- +## Быстрый старт -* [i18n-js](#i18n-js) -* [keysets](#keysets) -* [keysets-xml](#keysets-xml) +Чтобы собрать файлы интернализации для каждого языка, подключите необходимые технологии: -### i18n-js +```js +var I18NTech = require('enb-bem-i18n/techs/i18n'), + KeysetsTech = require('enb-bem-i18n/techs/keysets'), + FileProvideTech = require('enb/techs/file-provider'), + bemTechs = require('enb-bem-techs'); -Собирает `?.lang.<язык>.js`-файлы на основе `?.keysets.<язык>.js`-файлов. +module.exports = function(config) { + config.setLanguages(['en', 'ru']); -Используется для локализации в JS с помощью BEM.I18N. + config.node('bundle', function(node) { + // Получаем FileList + node.addTechs([ + [FileProvideTech, { target: '?.bemdecl.js' }], + [bemTechs.levels, levels: ['blocks']], + bemTechs.deps, + bemTechs.files + ]); + + // Собираем keyset-файлы для каждого языка + node.addTech([KeysetsTech, { lang: '{lang}' }]); + + // Собираем i18n-файлы для каждого языка + node.addTech([I18NTech, { lang: '{lang}' }]); + node.addTarget('?.lang.{lang}.js'); + }); +}; +``` +## Основные понятия + +### Исходные данные — keysets + +`keysets` — исходные файлы с переводами для поддержки интернационализации. Перевод представляет собой набор ключей и их значений. Ключ определяет, какое из значений должно быть выбрано для указанного языка. + +Пример для русского языка: + +```js +{ + hello: 'Привет!' +} +``` +Пример для английского языка: + +```js +{ + hello: 'Hello!' +} +``` + +Набор данных `ключ: 'значение'` передается с указанием контекста (`scope`). Обычно контекстом служит имя блока. + +Пример keysets-файла: + +```js +module.exports = { + scope: { + key: 'val' + } +}; +``` +Пример keysets-файла для русского языка: + +```js +module.exports = { + greeting: { + hello: 'Привет!'' + } +}; +``` -**Опции** +#### Расположение в файловой системе -* *String* **target** — Результирующий таргет. По умолчанию — `?.lang.{lang}.js`. -* *String* **lang** — Язык, для которого небходимо собрать файл. -* *String* **keysetsFile** — Исходный keysets-файл. По умолчанию — `?.keysets.{lang}.js`. +Переводы (keysets) хранятся в файлах `.js` (например, `en.js`). -**Пример** +Файлы `.js` для каждой БЭМ-сущности находятся в отдельной директории `.i18n` наряду с другими файлами технологий. -```javascript -nodeConfig.addTechs([ - [ require('enb-bem-i18n/techs/i18n-js'), { lang: 'all'} ], - [ require('enb-bem-i18n/techs/i18n-js'), { lang: '{lang}'} ] -]); ``` +block/ + block.css + block.js + block.i18n/ + ru.js # Исходный файл с переводом для русского языка. + en.js # Исходный файл с переводом для английского языка. +``` + +Также есть возможность объединять одинаковые для всех языков переводы в общие файлы: + +* В `bem-bl` — в файл `all.js`. +* В `bem-core` — в файл `.i18n.js`. + +Файлы `all.js` и `.i18n.js` Может содержать [ядро `i18n`](#Ядро-i18n) для библиотеки `bem-bl` и `bem-core`, соответственно. + +``` +common.blocks/ + block1/ + block1.css + block1.js + block1.i18n.js # Исходный файл с переводом, содержащий + # общие переводы для всех языков. + # Может содержать ядро `i18n` для библиотеки ` bem-core`. + block1.i18n/ # Директория для хранения файлов с переводами для разных языков. + en.js + ru.js + all.js # Исходный файл с переводом, содержащий + # общие переводы (в данном случае для + # русского и английского языков). + # Может содержать ядро `i18n` для библиотеки `bem-bl`. +``` + +### Ядро `i18n` + +Ядро `i18n` — это библиотека для интернационализации. Ядро находится в keysets-файлах (`.i18n.js` или `.all.js`) в одной из базовых библиотек блоков. + +Пакет `enb-bem-i18n` поддерживает разные реализации ядра интернационализации для библиотек `bem-bl` и `bem-core`. + +* В `bem-bl` — ядро `BEM.I18N`. +* В `bem-core` — ядро `i18n`. + +> Далее по тексту для названия ядра будет использоваться `i18n`. + +>Подробнее о расположении keysets-файлов, содержащих ядро, в файловой системе читайте в разделе [Расположение в файловой системе](#Расположение-в-файловой-системе). + +Ядро `i18n` в библиотеках `bem-core` и `bem-bl` хранится в keysets-файлах по-разному: + +* В `bem-bl` (файл `all.js`): + + ```js + { + all: { + '': { // пустая строка + /* код ядра */ + } + } + } + ``` + +* В `bem-core` (файл `i18n.js`): + + ```js + { + i18n: { + i18n: { + /* код ядра */ + } + } + } + ``` +Перед использованием ядро должно быть инициализировано данными из keysets-файлов. + +**Важно!** Для получения ядра необходимо добавить `mustDeps`-зависимость блокам, которые используют i18n. + +* Для bem-bl: + + ```js + ({ + mustDeps: { block: 'i-bem', elem: 'i18n' } + }) + ``` + +* Для bem-core: + + ```js + ({ + mustDeps: { block: 'i18n' } + }) +``` + +>Подробно про API использования ядра `i18n` читайте в разделе [API `i18n`](#api-i18n). + +## Работа с технологиями -### keysets +Данные из keysets-файлов `.js` во время сборки проходят несколько этапов: -Собирает `?.keysets.<язык>.js`-файлы на основе `*.i18n`-папок для указанных языков. +* [Объединение данных исходных файлов в один для указанного языка](#Объединение-данных) +* [Обработка данных из объединенного файла](#Обработка-данных) -**Опции** +### Объединение данных -* *String* **target** — Результирующий таргет. По умолчанию — `?.keysets.{lang}.js`. -* *String* **lang** — Язык, для которого небходимо собрать файл. +Технология [keysets](api.ru.md#keysets) объединяет исходные файлы `.js` для каждого языка в общий файл (`?.keysets..js`). Набор языков, для которых будут собраны `?.keysets..js`-файлы, задается с помощью опции [lang](#/api.ru.md#lang) в конфигурационном файле (`.enb/make.js`). -**Пример** +`?.keysets..js`-файл — это промежуточный результат сборки, который в дальнейшем используется технологией [i18n](api.ru.md#i18n). -```javascript -nodeConfig.addTechs([ - [ require('enb-bem-i18n/techs/keysets'), { lang: '{lang}' } ] -]); +Например, для блоков `greeting` и `login` результирующий `?.keysets.en.js`-файл будет собран следующим образом. + +Исходный файл `en.js` блока `greeting`: + +```js +module.exports = { + greeting: { + hello: 'Hello', + unknown: 'stranger' + } +}; +``` + +Исходный файл `en.js` блока `login`: + +```js +module.exports = { + login: { + login: 'Login', + pass: 'Password' + } +}; +``` + +Результирующий `?.keysets.en.js`-файл: + +```js +module.exports = { + greeting: { + hello: 'Hello', + unknown: 'stranger' + }, + login: { + login: 'Login', + pass: 'Password' + } +}; ``` -### keysets-xml +>Примеры всех вариантов использования ядра рассмотрены в [тестах к технологии](https://github.com/enb-bem/enb-bem-i18n/blob/master/test/techs/i18n-merge-keysets.test.js). + +### Обработка данных + +Данные из объединенного файла `?.keysets..js` обрабатываются технологией [i18n](/api.ru.md#i18n). Результатом работы является функция `i18n`, которая при вызове из [шаблонов](#В-шаблонах) или [клиентского JavaScript](#В-javascript) принимает ключ и отдает значение (строку) для конкретного языка. + +>API взаимодействия с ядром `i18n` описан в разделе [API `i18n`](#api-i18n). +Результатом являются `lang..js`-файлы, содержащие строки переводов, соответствующие запрошенным ключам. + +## Использование + +Функция `i18n` может использоваться: + +* [в JavaScript](#В-javascript) +* [в шаблонах](#В-шаблонах) -Собирает `?.keysets.<язык>.xml`-файлы на основе `?.keysets.<язык>.js`-файлов. +### В JavaScript -Используется для локализации xml-страниц. +Cпособы использования `i18n` в JavaScript зависят от наличия модульной системы и ее типа. Файлы могут подключаться как [в Node.js](#Использование-в-node.js), так и [в браузере](#Использование-в-браузере), независимо от используемой библиотеки (`bem-bl` или `bem-core`). -**Опции** +#### Использование в Node.js -* *String* **target** — Результирующий таргет. По умолчанию — `?.keysets.{lang}.js`. -* *String* **lang** — Язык, для которого небходимо собрать файл. +Скомпилированный файл подключается как модуль в формате CommonJS. -**Пример** +```js +var i18n = require('bundle.lang.en.js'); // Путь до скомпилированного файла -```javascript -nodeConfig.addTech(require('enb-bem-i18n/techs/keysets-xml')); +i18n('scope', 'key'); // 'val' ``` -Лицензия --------- +#### Использование в браузере + +В браузере применение скомпиллированных `?.lang..js`-файлов зависит от наличия модульной системы: + +* **В браузере без YModules как `BEM.I18N`** + + ```js + BEM.I18N('scope', 'key'); // Ядро `i18n` предоставляется в глобальную видимость в переменную `BEM.I18N`. + ``` + +* **В браузере с YModules как `i18n`-модуль** + + ```js + modules.require('i18n', function (i18n) { + i18n('scope', 'key'); // 'val' + }); + ``` + +>**Важно!** В проект с модульной системой ядро библиотеки интернационализации подключаются одинаково, как модуль `i18n`, вне зависимости от используемой библиотеки `bem-core` или `bem-bl`. + +### В шаблонах + +Использование функции `i18n` в шаблонах обеспечивают следующие пакеты, которые осуществляют поддержку `i18n` для ENB: + +* [enb-bemxjst-i18n](https://github.com/enb-bem/enb-bemxjst-i18n) +* [enb-xjst-i18n](https://github.com/enb-bem/enb-xjst-i18n) +* [enb-bh-i18n](https://github.com/enb-bem/enb-bh-i18n) + +## API `i18n` + +### Инициализация + +* **В `bem-bl`** + + ```js + var core = /* ... */, + keyset = { + hello: 'Привет!' + }, + lang = 'ru'; + + core.decl('greeting', keyset, lang); + core.lang(lang); + + core('greeting', 'hello'); // Привет! + ``` + +* **В `bem-core`** + + ```js + var core = /* ... */, + keysets = { + greeting: { + hello: "Привет!" + } + }; + + var i18n = core().decl(keysets); + + i18n('greeting', 'hello'); // Привет! + ``` + +### Параметризация значений + +Функция принимает следующие параметры: + +* **scope** — область видимости ключа. Обычно имя блока. +* **key** — ключ, соответствующий значению для указанного языка. +* **params** — входные данные для функции. + +Результат выполнения: строка, содержащая перевод. + +* **В `bem-bl`** + + Задавать значения ключей можно не только как строку. Также возможность параметризации значений реализована через XML. В строку передается XML, который обрабатывается с помощью специальной программы. + + ```js + { + 'scope-1': { + key: 'val' + }, + 'scope-2': { + key: 'Hello who!' + } + } + ``` + + +* **В `bem-core`** + + Задавать значения ключей можно не только как строку. Параметризация значений реализуется через функцию. + + Пример: + + ```js + { + 'scope-1': { + key: 'val' + }, + 'scope-2': { + key: function (params, i18n) { + return i18n(params.scope, params.key); + } + } + } + ``` + + ```js + modules.require('i18n', function (i18n) { + i18n('scope-2', 'key', { scope: 'scope-1', key: 'key' }); // Значение + }); + ``` + +## Отличия в работе + +### Переключение между языками во время исполнения + +* В `bem-bl` реализована возможность переключения между языками в реальном времени. +* В `bem-core` такой возможности нет. + +### Хранение общих keysets-файлов с переводами + +* В `bem-bl` переводы, одинаковые для всех языков, хранятся в файле `.i18n/all.js`. +* В `bem-core` — в файле `.i18n.js`. + +### Расположение ядра `i18n` + +* В `bem-bl` — элемент `i18n` блока `i-bem`. +* В `bem-core` — блок `i18n`. © 2014 YANDEX LLC. Код лицензирован [Mozilla Public License 2.0](LICENSE.txt). diff --git a/api.ru.md b/api.ru.md new file mode 100644 index 0000000..b3638b7 --- /dev/null +++ b/api.ru.md @@ -0,0 +1,205 @@ +# API технологий + +Пакет предоставляет следующие технологии: + +* [keysets](#keysets) — служебная технология для сбора исходных файлов с переводами. +* [i18n](#i18n) — технология, которая формирует общий бандл с переводами для каждого языка для дальнейшего использования. +* [i18n-keysets-xml](#i18n-keysets-xml) — технология для локализации сервисов, использующих XSLT для шаблонизации. + +## keysets + +Служебная технология. Собирает данные (`keysets`) для указанного языка в `?.keysets..js`-файл на основе `.js`-файлов. + +### Опции + +* [target](#target) +* [lang](#lang) +* [dirsTarget](#dirstarget) +* [sourceDirSuffixes](#sourcedirsuffixes) + +#### target + +Тип: `String`. По умолчанию: `?.keysets..js`. + +Имя файла, куда будет записан результат сборки необходимых `.js`-файлов проекта — скомпилированный файл `?.keysets..js`. + +`?.keysets..js`-файл — это промежуточный результат сборки, который в дальнейшем используется технологией [i18n](#i18n). + +#### lang + +Тип: `String`. Обязательная опция. + +Язык, для которого необходимо собрать файл. + +Допустимые значения: + +* **'lang'** — значение языка (например, `'en'`, `'ru'`), для которого будут собраны данные (`keysets`) из файлов `.js`. + +* **'{lang}'** — специальная директива, которая вызывает технологию необходимое количество раз с поочередной подстановкой в `'lang'` всех языков, указанных в параметрах функции `config.setLanguages()`. + +#### dirsTarget + +Тип: `String`. По умолчанию: `?.i18n`. + +Имя таргета, откуда будет доступен список исходных директорий для сборки. Список директорий предоставляет технология [files](https://github.com/enb-bem/enb-bem-techs/blob/master/docs/api.ru.md#files) пакета [enb-bem-techs](https://ru.bem.info/tools/bem/enb-bem-techs/readme/). + +#### sourceDirSuffixes + +Тип: `String | String[]`. По умолчанию: `['.i18n']`. + +Суффиксы директорий, по которым они отбираются для дальнейшей сборки. + + +------------------------------------- +**Пример** + +```js +var KeysetsTech = require('enb-bem-i18n/techs/keysets'), + FileProvideTech = require('enb/techs/file-provider'), + bemTechs = require('enb-bem-techs'); + +module.exports = function(config) { + config.setLanguages(['en', 'ru']); + + config.node('bundle', function(node) { + // Получаем FileList + node.addTechs([ + [FileProvideTech, { target: '?.bemdecl.js' }], + [bemTechs.levels, levels: ['blocks']], + bemTechs.deps, + bemTechs.files + ]); + + // Собираем keyset-файлы для каждого языка + node.addTech([KeysetsTech, { lang: '{lang}' }]); + node.addTarget('?.keysets.{lang}.js'); + }); +}; +``` + +## i18n + +Собирает `?.lang..js`-файлы для отдельных языков на основе данных из `?.keysets..js`-файлов, полученных в результате использования технологии [keysets](#keysets). + +`i18n` — технология сборки, которая транслирует данные из `?.keysets..js`-файлов в JavaScript. + +Технология `i18n` инициализирует ядро `i18n` данными из объединенных keyset-файлов и возвращает функцию `BEM.i18n`, которую можно использовать из [шаблонов](/README.md#в-шаблонах) или [клиентского JavaScript](README.md#В-javascript). + +>API функции `i18n` описан в разделе [API `i18n`](README.md#api-i18n). + +### Опции + +* [target](#target-1) +* [lang](#lang-1) +* [keysetsFile](#keysetsаile) + +#### target + +Тип: `String`. По умолчанию: `?.lang..js`. + +Имя файла, куда будет записан результат сборки необходимых данных из `?.keysets..js`-файла — скомпилированный файл `?.lang..js`. + + +#### lang + +Тип: `String`. Обязательная опция. + +Язык, для которого необходимо собрать финальный файл, содержащий строки переводов. + +Допустимые значения: + +* **'lang'** — значение языка (например, `'en'`, `'ru'`), для которого будут собраны данные (`keysets`) из файлов `.js`. + +* **'{lang}'** — специальная директива, которая вызывает технологию необходимое количество раз с поочередной подстановкой в `'lang'` всех языков, указанных в параметрах функции `config.setLanguages()`. + +#### keysetsFile + +Тип: `String`. По умолчанию — `?.keysets..js`. + +`?.keysets..js`-файл — это результат выполнения [keysets](#keysets) — набор данных (`keysets`) для указанного языка, который используется технологией [i18n](#i18n) для формирования `?.lang..js`-файлов. + +------------------------------------- +**Пример** + +```js +var I18NTech = require('enb-bem-i18n/techs/i18n'), + KeysetsTech = require('enb-bem-i18n/techs/keysets'), + FileProvideTech = require('enb/techs/file-provider'), + bemTechs = require('enb-bem-techs'); + +module.exports = function(config) { + config.setLanguages(['en', 'ru']); + + config.node('bundle', function(node) { + // Получаем FileList + node.addTechs([ + [FileProvideTech, { target: '?.bemdecl.js' }], + [bemTechs.levels, levels: ['blocks']], + bemTechs.deps, + bemTechs.files + ]); + + // Собираем keyset-файлы для каждого языка + node.addTech([KeysetsTech, { lang: '{lang}' }]); + + // Собираем i18n-файлы для каждого языка + node.addTech([I18NTech, { lang: '{lang}' }]); + node.addTarget('?.lang.{lang}.js'); + }); +}; +``` + +## i18n-keysets-xml + +Собирает `?.keysets..xml`-файлы на основе `?.keysets..js`-файлов. + +Технология `i18n-keysets-xml` применяется для локализации сервисов, использующих [XSLT](https://github.com/veged/xjst) для шаблонизации. +Используется для локализации XML-страниц. + +### Опции + +* [target](#target-2) +* [lang](#lang-2) + +#### target + +Тип: `String`. По умолчанию — `?.keysets.{lang}.js`. + +Результирующий XML-файл. + +#### lang + +Тип: `String`. Обязательная опция. + +Язык, для которого небходимо собрать файл. + +----------------------------- +**Пример** + +```js +var KeysetsTech = require('enb-bem-i18n/techs/keysets'), + KeysetsXMLTech = require('enb-bem-i18n/techs/keysets-xml'), + FileProvideTech = require('enb/techs/file-provider'), + bemTechs = require('enb-bem-techs'); + +module.exports = function(config) { + config.setLanguages(['en', 'ru']); + + config.node('bundle', function(node) { + // Получаем FileList + node.addTechs([ + [FileProvideTech, { target: '?.bemdecl.js' }], + [bemTechs.levels, levels: ['blocks']], + bemTechs.deps, + bemTechs.files + ]); + + // Собираем keyset-файлы для каждого языка + node.addTech([KeysetsTech, { lang: '{lang}' }]); + + // Собираем XML-файлы для каждого языка + node.addTech([KeysetsXMLTech, { lang: '{lang}' }]); + node.addTarget('?.keysets.{lang}.js'); + }); +}; +```