Статьи

Угловая локализация и интернационализация

При переводе приложения на Angular вам нужно сделать несколько вариантов, прежде чем погрузиться в процесс интернационализации (i18n). В этом посте мы подробнее рассмотрим различные варианты угловой локализации и i18n, укажем на преимущества и недостатки и приведем несколько примеров.

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

Когда вы используете встроенные инструменты для вашей угловой локализации, вам нужно принять второе решение: хотите ли вы использовать компилятор Ahead-of-Time (AOT) или компилятор Just-in-Time (JIT). С помощью AOT ваше приложение может обслуживаться быстро, а ваши пользователи получают выгоду от повышения производительности. Недостатком является то, что вам нужно обслуживать приложение для каждой локали из-за того, что вся информация, включая контент, встроена при компиляции приложения. Решение о том, какой язык должен быть показан пользователям, должно приниматься серверной логикой или параметрами URL. Если вы выберете JIT, переводы будут динамичными, но вы должны позаботиться о том, чтобы обеспечить переводы в вашем приложении. Однако имейте в виду, что в этом случае производительность может снизиться.

Также есть возможность выбрать стороннюю библиотеку для интернационализации. В качестве примера мы выберем ngx-translate, одну из самых популярных библиотек. Библиотека может использоваться как для JIT-, так и для AOT-скомпилированных версий вашего приложения.

Угловая локализация со встроенным I18n

Сначала мы подробнее рассмотрим встроенные инструменты Angular. Мы покажем вам, как настроить вашу угловую локализацию и как на самом деле переводить контент. Затем мы рассмотрим такие вопросы, как плюрализация и заполнители в вашем контенте. И последнее, но не менее важное, мы представим базовый рабочий процесс интеграции Phrase в ваш процесс разработки.

Настроить

С AOT нет ничего, что можно настроить для запуска интернационализации в вашем приложении. Единственное, что нужно для тестирования разных локалей — это запуск вашего приложения с кодом локали в качестве параметра. Вот пример, если вы хотите проверить немецкие переводы, используя код локали de:

ng serve --aot --locale de

Если вы используете JIT, вам нужно определить вашего LOCALE_IDпровайдера в вашем основном модуле:

import { LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from '../src/app/app.component';

@NgModule({
      imports: [ BrowserModule ],
        declarations: [ AppComponent ],
        providers: [ { provide: LOCALE_ID, useValue: 'de' } ],
        bootstrap: [ AppComponent ]
})
export class AppModule { }

Это все, что вам нужно для начала работы с интернационализацией в приложении Angular с использованием встроенных инструментов.

Извлекайте нелокализованный контент

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

CLI Angular предоставляет команду, которая экспортирует контент, помеченный i18nатрибутом (об этом вы узнаете в следующем разделе). К сожалению, вы должны пометить контент самостоятельно. Как только это будет сделано, вы можете сгенерировать файл, который включает каждый исходный перевод:

ng x18n

По умолчанию это сгенерирует файл message.xlfXLIFF 1.2 . С помощью этого файла вы можете начать переводить контент на несколько языков.

Рекомендуется создать каталог, в котором находится каждый контент, который нуждается в локализации, например ./locale. Теперь скопируйте ваш сгенерированный файл в новую папку и включите информацию о локали в имя файла. Например, messages.en.xlfесли контент на английском или messages.de.xlfнемецкий.

Переведите ваш контент

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

<h1 i18n>My Headline<h1>

Атрибут i18nпозаботится о локализации этого контента. Мы настоятельно рекомендуем вам добавить идентификатор для перевода, в противном случае он будет сгенерирован Angular, что приведет к случайному идентификатору.

<h1 i18n="@@my_meaningful_id">My Headline<h1>

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

<h1 i18n="This is a very good description@@my_meaningful_id">My Headline<h1>

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

<img [src]="a localized images" i18n-title title="the localized title of the image" i18n-x="@@meaningful_id" />

Это работает с любым атрибутом любого элемента.

К сожалению, локализация контента где-то, кроме HTML-файла, пока невозможна. На GitHub уже есть открытая проблема , но она кажется довольно сложной, поэтому для ее реализации может потребоваться некоторое время. Если вам нужна эта функция, мы рекомендуем поближе познакомиться с библиотекой ngx-translate.

Использование плюрализации и заполнителей в вашем контенте

Angular по умолчанию использует формат сообщений ICU . С этим форматом вы можете практически реализовать любой тип множественного числа и заполнителей, которые вы можете себе представить. Вот базовый пример, за которым следует продвинутый:

<h1>Hello {{ name }}</h1>
<span i18n>
    Updated: {minutes, plural,
    =0 {just now}
    =1 {one minute ago}
    other {{{minutes}} minutes ago by {gender, select, m {male} f {female} o {other}}}}
</span>

Первый просто здоровается с именем. Во втором примере будет напечатано различное содержимое в зависимости от значения minutes. Если минуты не равны ни нулю, ни единице, содержание  other дела будет взято, где содержание зависит от пола человека. Формат сообщений ICU действительно мощный, но также немного сложный для пользователей, которые к нему не привыкли. Вы можете прочитать больше о формате здесь.

Угловая локализация с Ngx-Translate

ngx-translate — это библиотека интернационализации для Angular, которая пытается сократить разрыв между отсутствующими функциями встроенных функций интернационализации.

Настроить

Для его настройки сначала необходимо установить библиотеку.

npm install @ngx-translate/core --save

После этого вам необходимо настроить TranslateModuleзагрузку файлов i18n, в которых находится переведенный контент.

import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpClientModule, HttpClient} from '@angular/common/http';
import {TranslateModule, TranslateLoader} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {AppComponent} from './app';

export function HttpLoaderFactory(http: HttpClient) {
        return new TranslateHttpLoader(http);
}

@NgModule({
        imports: [
                    BrowserModule,
                    HttpClientModule,
                    TranslateModule.forRoot({
                            loader: {
                                        provide: TranslateLoader,
                                        useFactory: HttpLoaderFactory,
                                        deps: [HttpClient]
                            }
                    })
            ],
            bootstrap: [AppComponent]
})
export class AppModule { }

Это загрузит переводы с /assets/i18n/<locale-code>.json. <locale-code>является заполнителем для всех языков, которые вы предоставляете.

Следующий шаг инициализирует TranslationService. Здесь вы должны указать приложению, какой должен быть язык по умолчанию. Язык по умолчанию будет использоваться в тех случаях, когда перевода на целевом языке не существует.

 export class AppComponent {
         param = {value: 'world'};

             constructor(translate: TranslateService) {
                 translate.setDefaultLang('en');
                 translate.use('en');
             }
 }

Ваше приложение теперь готово для i18n. Вы также можете настроить ngx-translate для работы с AOT. Для получения более подробной информации, пожалуйста, посетите официальную страницу, где отображается дополнительная информация о настройке.

Извлекайте нелокализованный контент

ngx-translate не может экспортировать ваш контент автоматически. Но есть плагин, который может извлекать любой переводимый контент и сохранять его в виде файлов JSON или Gettext. \

Посетите страницу GitHub для получения дополнительной информации и базовой интеграции.

Перевести контент

ngx-translate предоставляет три способа локализации контента. Вы можете либо использовать TranslationService, то TranslatePipe, или TranslateDirectiveполучить локализованный контент.

Используйте, TranslationServiceесли вам нужно локализовать контент в одной из ваших служб или контроллеров.

translate.get('my_meaningful_id').subscribe((res: string) => { ... });

Для перевода содержимого ваших HTML-файлов вы можете использовать TranslatePipe:

<h1>{{ 'my_meaningful_id' | translate }}

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

<div translate>my_meaningful_id</div>

Локализация отдельных атрибутов тега HTML невозможна. Поэтому вам нужно настроить весь тег как перевод, что не составляет никакой проблемы. Вам нужно только использовать innerHTMLатрибут, и он должен работать из коробки:

<h1 [innerHTML]="'key_id_with_html_content' | translate"></h1>

Использование плюрализации и заполнителей в вашем контенте

Заполнители можно заполнить, просто передав хэш при вставке. Вот примеры вышеперечисленных способов:

translate.get('my_meaningful_id', { placeholder_name: value }).subscribe((res: string) => {
    ...
});
# in your component
params = { placeholder_name: value }
...
#in your view
<h1>{{ 'my_meaningful_id' | translate:params }}
<div translate="my_meaningful_id" translateParams="{ placeholder_name: value }">my_meaningful_id</div>

Плюрализация не работает из коробки. Вам нужно использовать i18nPluralPipe из Angular API для решения этой проблемы.

Здесь вы можете найти больше информации об этом на GitHub .

Существует также плагин для использования формата сообщений ICU.

Автоматизировать рабочий процесс

Очень легко интегрировать PhraseApp в ваш поток сборки пряжи / npm. Вы можете просто добавить команду PhraseApp pull в свои сценарии в package.json.

Вот пример того, как должен выглядеть ваш скрипт:

"scripts": { 
  "ng": "ng", 
  "start": "ng serve",
  "build": "phraseapp pull && ng build", 
  "localize": "phraseapp push", 
  "test": "ng test", 
  "lint": "ng lint", 
  "e2e": "ng e2e" 
}

Есть некоторые действия, которые мы должны осуществить. Первый — это yarn localize/ npm localize. Это подтолкнет все переводы в PhraseApp, где контент может быть переведен вашими переводчиками или вы можете заказать переводы. Второе действие — это yarn build/ npm build. Здесь мы добавили phraseapp pull, чтобы всегда иметь актуальные переводы перед выпуском новой версии.

Чтобы использовать эту конфигурацию, вам нужно только установить наш CLI Tool и создать конфигурацию в вашем проекте.

Заключение

Для вашей локализации Angular и i18n ngx-translate кажется более полным и удобным, чем встроенные инструменты Angular. Плагины для ngx-translate добавляют большинство недостающих функций, таких как формат сообщений ICU и извлечение контента для легкого запуска. Но мы считаем, что Angular проделали очень хорошую работу над своими инструментами i18n. Простая настройка — одно из самых больших преимуществ функции Angular i18n, особенно если вы используете перевод только в своих файлах просмотра.