Найти в Дзене
Logonok

Локализация веб-приложения

Современное веб-приложение должно уметь подстраиваться под пользователя, обеспечивая понятный и дружелюбный интерфейс. Динамическая локализация является одним из таких умений. В декларативном фреймворке Evado локализация поддерживается на двух уровнях. Первый уровень - это когда перевод осуществляется на сервере, при подготовке контента. Второй - это перевод непосредственно в браузере клиента. Серверная локализация За локализацию на стороне сервера отвечает компонент i18n. Для его конфигурации используются следующие параметры: Данные для перевода хранятся в источниках сообщений (по умолчанию - это файлы в папке message). Источник объединяет сообщения в отдельную категорию. Например, тексты для рассылок или уведомлений. Ключи сообщений Обычно ключом (идентификатором) сообщения является фраза на исходном языке источника. В коде указывается ключевая фраза, а при переводе подставляется соответствующая ей фраза на целевом языке. Если перевод отсутствует, то будет отображен ключ. В некоторы
Оглавление

Современное веб-приложение должно уметь подстраиваться под пользователя, обеспечивая понятный и дружелюбный интерфейс. Динамическая локализация является одним из таких умений.

В декларативном фреймворке Evado локализация поддерживается на двух уровнях. Первый уровень - это когда перевод осуществляется на сервере, при подготовке контента. Второй - это перевод непосредственно в браузере клиента.

Серверная локализация

За локализацию на стороне сервера отвечает компонент i18n. Для его конфигурации используются следующие параметры:

  • language - кодовое название языка приложения.
  • sources - конфигурация источников сообщений (см. ниже).
  • sourceLanguage - кодовое название языка, который является ключом для сообщений (по умолчанию для всех источников, но может быть переопределен в конкретном источнике).

Данные для перевода хранятся в источниках сообщений (по умолчанию - это файлы в папке message). Источник объединяет сообщения в отдельную категорию. Например, тексты для рассылок или уведомлений.

Ключи сообщений

Обычно ключом (идентификатором) сообщения является фраза на исходном языке источника. В коде указывается ключевая фраза, а при переводе подставляется соответствующая ей фраза на целевом языке. Если перевод отсутствует, то будет отображен ключ.

В некоторых случаях, лучшим вариантом будет использование специальных ключей (например, app.shop.notify.success) вместо обычных фраз. Для этого необходимо для источника указать параметр forceTranslation: true. В этом случае, сначала производится поиск перевода по ключу для целевого языка, если он отсутствует, то ищется перевод для исходного языка, а если и он отсутствует, то тогда отобразится сам ключ.

Методы перевода

Для удобства использования методы перевода вынесены в разные части приложения, но фактически они являются обертками для основного метода translate из компонента i18.

  • i18.translate (message, params, source, language) - переводит сообщение с указанными параметрами (см. ниже), категорией сообщений (источником) и целевым языком.
  • [module].translate (message, params, source = 'app') - переводит сообщение, используя по умолчания основную категорию и целевой язык приложения.
  • [controller].translate (message, params, source = 'app') - переводит сообщение, используя по умолчания основную категорию приложения и целевой язык из текущего запроса. В шаблонах представления метод [controller].translate доступен через псевдоним _t.

Динамические значения сообщения

Часто бывает необходимо не просто найти соответствие фразы на другом языке, но и добавить в неё некоторые значения. Для этого в сообщении указываются специальные метки. Например, 'Value must be no greater than {max}': 'Значение должно быть не больше {max}'. Сами значения передаются через параметры во время перевода:
translate('Value must be no greater than {max}', { max: 12 })
.

Каждое динамическое значение может быть автоматически отформатировано в соответствии с целевым языком. Типичный пример - это отображение даты:

  • Источник: 'Current date: {now}': 'Текущая дата: {now}'.
  • Метод: translate('Current date: {now}', {now: [new Date, 'dateLongFormat']}).
  • Результат на английском: Current date: May 11, 2023.
  • Результат на русском: Текущая дата: 11 мая 2023.

Явное форматирование значений (в том числе с учетом языка) может осуществляться перед переводом с помощью компонента formatter.

Тип Message

Если над сообщением необходимо произвести какие-либо дополнительные действия (передавать его между функциями), то лучшим решением будет создание объекта класса Message, который содержит в себе как ключевую фразу, так и значения динамических параметров.

Перевести объект Message можно через его собственный метод translate, передав ему соответствующий компонент i18n.

Клиентская локализация

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

Файлы источников сообщений создаются в директории доступной для внешних запросов (например, web/app/message/ru.js). Данные оформлены в объекты ключ - значение (исходное сообщение - целевое сообщение).

Изначально в приложении существует единственная категория сообщений - Jam.i18n.defaults. Доступ к ней осуществляется по умолчанию - без указания категории. Если вы захотите добавить собственные сообщения в эту категорию, то обязательно сохраните существующие, расширив объект своими данными.

Иерархия категорий

Новые категории сообщений подключаются напрямую к классу Jam.I18n. Например, Jam.I18n.myCategory = { 'My text': 'Мой текст' }.

Если в название категории имеется точка, то формируется иерархия, которая определяет последовательность поиска перевода в категориях. Например, созданы следующие категории:
Jam.I18n['meta'] = { 'Name': 'Название' },
Jam.I18n['meta.myClass'] = { 'File': 'Файл' },
Jam.I18n['meta.myClass.myAttr'] = { 'Edit': 'Редактировать' }.

При вызове
Jam.t('Name', 'meta.myClass.myAttr') поиск перевода будет происходить последовательно в категориях meta.myClass.myAttr, meta.myClass и meta. Первое найденное значение и будет возвращено.

Перевод с помощью HTML-разметки

Перевод на клиенте может быть сделан, как непосредственно с помощью вызова метода Jam.i18n.translate (псевдоним - Jam.t), так и автоматически - по данным HTML-разметки. Если указан атрибут data-t, то содержимое HTML-тэга будет переведено. Например, <span data-t="">Birth date</span> превратится в <span data-t="">Дата рождения</span>. Можно указать конкретную категорию сообщений - <span data-t="profile">Age</span>.

Кроме содержимого HTML-тэга переводятся и некоторые его атрибуты (по умолчанию - title и placeholder). Для них так же используется категория указанная в data-t, но ее можно изменить на любую другую с помощью атрибутов data-t-title и data-t-placeholder. Задать собственный список атрибутов для перевода можно в data-t-attrs.

Заключение

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

Пример демо-приложения доступен в открытом репозитории.

Декларативный фреймворк Evado: Создавай! Наполняй! Управляй! Представляй!
Декларативный фреймворк Evado: Создавай! Наполняй! Управляй! Представляй!