国際化へのアングルプロジェクトのアプローチ

1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...

Angularの公式ウェブサイトでは、プロジェクトの国際化は複数の努力、長年にわたる献身と決意を必要とする挑戦的な課題です。
この記事では、静的文書(html)とtsファイルのコピーの国際化を含む角度のあるプロジェクトの国際化について紹介します。

背景

角度:5.0
角度Cli:1.6.1(1.5.xはOK)
NG-ZORRO:0.6.8

角度i18n

i18nテンプレートの翻訳プロセスには4つの段階があります。

コンポーネントテンプレートで翻訳する必要がある静的テキスト情報(i18nとマークされている)をマークします。
Angularのi18nツールは、業界標準の翻訳ソースファイル(たとえば、ng xi18nを使用した.xlfファイル)にタグ付き情報を抽出します。
この記事では、xlfファイルを使用してjson形式のファイル出力に変換し、最終的にjsonファイルをxlf形式に変換して戻します。翻訳者は、このファイルを編集し、抽出したテキストメッセージをターゲット言語に翻訳して返します。ファイル)。
Angularコンパイラは、翻訳されたファイルをインポートし、元の情報を翻訳されたテキストに置き換え、アプリケーションの新しいターゲット言語バージョンを生成します。

サポートされている言語ごとに個別のプロジェクトバージョンを構築して展開できます。翻訳されたxlfファイルを置き換えるだけです。

テンプレートファイルの使い方は?

I18nは、いくつかの使用方法を提供します。また、単数形と複数形の翻訳方法も提供しています。 次に、別のhtmlファイルを使用して、いくつかの使用方法を紹介します。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Angular i18n</title>
</head>
<body>
<h1 i18n="Site Header|An introduction header for i18n [email protected]@stTitle">Angular 国际化项目</h1>
<p>
<span i18n="@@agDescription">国际化是一项很具有挑战性,需要多方面的努力、持久的奉献和决心的任务。</span>
<span class="delete" i18n-title="@@agDelete" title="删除"></span>
</p>
<p><ng-container [email protected]@agLetGo>让我们现在开始吧!</ng-container>朋友!</p>
</body>
</html>

上記のコードはいくつかのi18nの使い方を示しています:

1. i18n属性タグを使用してください(title: [email protected] @id、タイトルと説明は、翻訳者がコピーの意味をより理解するのに役立ちます。追加するかどうかは、プロジェクトのステータスによって異なります)

静的タグに直接i18nタグを付けることができます。


<span i18n="@@agDescription"></span>

生成されるxlf(xml)フィールド形式は次のとおりです。


<trans-unit id="agDescription" datatype="html">
<source>国际化是一项很具有挑战性,需要多方面的努力、持久的奉献和决心的任务。</source>
<context-group purpose="location">
<context context-type="sourcefile">xxx.ts</context>
<context context-type="linenumber">linenum</context>
</context-group>
</trans-unit>

2、タイトルにi18n属性を追加する

HTMLタグ属性の場合は、i18nを追加することもできます。


<span class="delete" i18n-title="@@agDelete" title="删除"></span>

上記のように生成されたxlf(xml)形式

3.要素を作成せずにテキストを翻訳する

私たちはたまに複数の文を1つの文章に入れることがあります。スパンを追加すると、ラベルの要素がたびにラップされ、ページレイアウトに重大な影響を与える可能性があります。


<p>
<ng-container [email protected]@agLetGo>让我们现在开始吧!</ng-container>朋友!
</p>

そのページの


<p>
<!->
LET'S GO朋友!
</p>

* ng-containerはコメントブロックになりますが、これはページレイアウトには影響しません(特にスタイルスタイルが適用されている場合)

ラベリング後、単にng xi18n、通常はmessage.xlfを実行してxlfファイルを作成することができます。カスタマイズする必要がある場合は、公式Angular CLIのWebサイトにアクセスできます。

XLFとJSONの変換

jlsonメソッドへのXlf

私は個人的に操作するためにxml2jsライブラリを使用して、簡単なコードは次のとおりです:


const fs = require('fs');
xml2js = require('xml2js');
var parser = new xml2js.Parser();
fs.readFile(fileName, 'utf8', (err, data) => {
parser.parseString(data, function (err, result) {
// 读取新文件全部需要翻译的数据,并对比已翻译的进行取舍,具体转换成的格式结构可自行查看
result['xliff']['file'][0]['body'][0]['trans-unit'].forEach((item) => {
var itemFormat = {
"key" : item['$']['id'],
"value": item['source'][0]
};
// 执行相关操作,key-value形式是为了统一翻译文件结构,可按需定义
})
});
});

Jsonからxlfへのメソッド


function backToXLF(translatedParams) {
// 文件格式可自行参考angular.cn官网的例子
var xlfFormat = {
"xliff": {
"$"  : {
"version": "1.2",
"xmlns" : "urn:oasis:names:tc:xliff:document:1.2"
},
"file": [
{
"$"  : {
"source-language": "en",
"datatype"    : "plaintext",
"original"    : "ng2.template"
},
"body": [
{
"trans-unit": []
}
]
}
]
}
};
if (translatedParams instanceof Array) {
// 获取原始名称
translatedParams.forEach((data) => {
var tmp = {
"$"   : {
"id"   : data.key,
"datatype": "html"
},
"source": [i18nItemsOrigin[data.key]], // 这里的i18nItemsOrigin是json格式,属性名为key值,表示原始文案
"target": [data.value]
};
// 数组,json项
xlfFormat['xliff']['file'][0]['body'][0]['trans-unit'].push(tmp);
});
}
var builder = new xml2js.Builder();
var xml = builder.buildObject(xlfFormat);
return xml;
}

これで、テキスト情報の抽出と翻訳されたファイルの翻訳が完了しました。次に、翻訳されたコピーをプロジェクトに適用する必要があります。

翻訳ファイルを展開する

srcディレクトリの新しいロケールフォルダ、変換されたdemo.en-US.xlfファイルをディレクトリに変換する

新しいi18n-providers.tsがアプリフォルダの下にあります


import {
LOCALE_ID,
MissingTranslationStrategy,
StaticProvider,
TRANSLATIONS,
TRANSLATIONS_FORMAT
} from '@angular/core';
import { CompilerConfig } from '@angular/compiler';
import { Observable } from 'rxjs/Observable';
import { LOCALE_LANGUAGE } from './app.config'; // 自行定义配置位置
export function getTranslationProviders(): Promise<StaticProvider[]> {
// get the locale string from the document
const locale = LOCALE_LANGUAGE.toString();
// return no providers
const noProviders: StaticProvider[] = [];
// no locale or zh-CN: no translation providers
if (!locale || locale === 'zh-CN') {
return Promise.resolve(noProviders);
}
// Ex: 'locale/demo.zh-MO.xlf`
const translationFile = `./locale/demo.${locale}.xlf`;
return getTranslationsWithSystemJs(translationFile)
.then((translations: string) => [
{ provide: TRANSLATIONS, useValue: translations },
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
{ provide: LOCALE_ID, useValue: locale },
{
provide: CompilerConfig,
useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error })
}
]).catch(() => noProviders); // ignore if file not found
}
declare var System: any;
// 获取locale文件
function getTranslationsWithSystemJs(file: string) {
let text = '';
const fileRequest = new XMLHttpRequest();
fileRequest.open('GET', file, false);
fileRequest.onerror = function (err) {
console.log(err);
};
fileRequest.onreadystatechange = function () {
if (fileRequest.readyState === 4) {
if (fileRequest.status === 200 || fileRequest.status === 0) {
text = fileRequest.responseText;
}
}
};
fileRequest.send();
const observable = Observable.of(text);
const prom = observable.toPromise();
return prom;
}

main.tsファイルは次のように変更されています。


import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { getTranslationProviders } from './app/i18n-providers';
if (environment.production) {
enableProdMode();
}
getTranslationProviders().then(providers => {
const options = { providers };
platformBrowserDynamic().bootstrapModule(AppModule, options)
.catch(err => console.log(err));
});

.angular-cli.jsonにロケールディレクトリを追加し、別々にパッケージ化することを忘れないでください。

このようにして、静的テキストの翻訳作業は基本的に完了しましたが、tsファイルやサードパーティフレームワーク属性のファイルをコピーするなどのダイナミックテキストはどのように翻訳されますか? 以下では、tsファイルとNG-ZORROフレームワークの動的テキスト変換プログラムを紹介します。

TsファイルのコピーとNG-ZORROフレームワークのコピー変換

具体的なアイデア

パイプ呼び出しサービスメソッドを使用して、jsonオブジェクトの変換結果と一致する対応する一意のid値に従って、レンダリングフロントエンドに戻ります.NG-ZORROフレームワークの国際化を参照してください。

まず第一に、すべての3層構造のjson変換オブジェクトの形式を定義します。動的変数は%%でラップする必要があります。これはプロジェクト構造と関連しているだけでなく、late形式とi18n形式の統一を容易にします。


{
"app": {
"base": {
"hello": "文件文案",
"userCount": "一共%num%人"
}
}
}

フォーマットが設定され、我々はサービス処理を定義し続けます

ここでNG-ZORROの国際化プログラムを再利用することで、開発を簡単にすることができます。興味のある人は、ソースコードを参照してください。


*** TranslateService ***
import { Injectable } from '@angular/core';
// 引入语言配置和国际化文件文案对象
import { LOCALE_LANGUAGE } from '../app.config';
import { enUS } from '../locales/demo.en-US';
import { zhCN } from '../locales/stream.zh-CN';
@Injectable()
export class TranslateService {
private _locale = LOCALE_LANGUAGE.toString() === 'zh-CN' ? zhCN : enUS;
constructor() {
}
// path为app.base.hello格式的字符串,这里按json层级取匹配改变量
translate(path: string, data?: any): string {
let content = this._getObjectPath(this._locale, path) as string;
if (typeof content === 'string') {
if (data) {
Object.keys(data).forEach((key) => content = content.replace(new RegExp(`%${key}%`, 'g'), data[key]));
}
return content;
}
return path;
}
private _getObjectPath(obj: object, path: string): string | object {
let res = obj;
const paths = path.split('.');
const depth = paths.length;
let index = 0;
while (res && index < depth) {
res = res[paths[index++]];
}
return index === depth ? res : null;
}
}

このようにして、パイプ内のサービスの翻訳メソッドを呼び出すだけで済みます。


*** NzTranslateLocalePipe ***
import { Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from '../services/translate.service';
@Pipe({
name: 'nzTranslateLocale'
})
export class NzTranslateLocalePipe implements PipeTransform {
constructor(private _locale: TranslateService) {
}
transform(path: string, keyValue?: object): string {
return this._locale.translate(path, keyValue);
}
}

さて、私たちの処理ロジックが完全に終わったので、ここで


*** NG-ZORRO 控件 ***
<nz-input [nzPlaceHolder]="'app.base.hello'|nzTranslateLocale"></nz-input> // 无动态参数
<nz-popconfirm [nzTitle]="'app.base.userCount'|nzTranslateLocale: {num:users.length}" ...>
... // 有动态参数
</nz-popconfirm>
*** ts文件 ***
export class AppComponent implements OnInit {
demoTitle='';
users = ['Jack', 'Johnson', 'Lucy'];
constructor(privete translateService: TranslateService) {
}
ngOnInit() {
this.demoTitle = this.translateService.translate('app.base.hello');
}
}

上記のプロセスは、基本的に大部分の角度のあるプロジェクトの国際化要件を満たすことができます。より複雑な国際化が必要な場合は、議論を歓迎します。

要約

Angular to 5.0の国際化は比較的簡単で、i18nタグを適切な場所に配置するだけで、必要なコピーを素早く簡単に抽出することができます。翻訳されたファイルを扱う方法は、人によって異なります。変換するのに役立つことができます(この記事ではnodejsを使用しています)。

NG-ZORROの国際化ソリューションは、この点で欠点を補っており、プロジェクトの国際化を完了するために簡単に統合することができます。 国際化特別なチームサポートがない場合、翻訳は非常に難しく、伝統的な中国語、繁体字中国語、台湾語など、考慮すべき事項が多く、文法は同じではありません。

参照リスト

Angular's International(i18n)オンラインの例
NG-ZORROロケールの国際化


1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...
      この投稿は審査処理中  | 元のサイトへ