Home > Article > Web Front-end > How to implement internationalization using Angular (detailed tutorial)
This article mainly introduces the method of realizing internationalization of Angular projects. Now I will share it with you and give you a reference.
As the angular official website says, project internationalization is a challenging task that requires multi-faceted efforts, lasting dedication and determination.
This article will introduce the internationalization plan of the angular project, involving the internationalization of static files (html) and ts file copywriting.
How to use it in template file?
i18n provides several ways to use it, and also provides translation methods for singular and plural numbers (I haven’t used it personally, and it feels inconvenient). Next, a separate html file will be used to introduce several usage methods.<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Angular i18n</title> </head> <body> <h1 i18n="Site Header|An introduction header for i18n Project@@stTitle">Angular 国际化项目</h1> <p> <span i18n="@@agDescription">国际化是一项很具有挑战性,需要多方面的努力、持久的奉献和决心的任务。</span> <span class="delete" i18n-title="@@agDelete" title="删除"></span> </p> <p><ng-container i18n=@@agLetGo>让我们现在开始吧!</ng-container>朋友!</p> </body> </html>The above code shows several ways to use i18n: 1. Use i18n attribute tags (explanatory copy can be added, the format is such as: title|description@@id, title and description can help translators better understand the meaning of the copywriting. Whether to add it depends on the situation of your own project) You can directly tag the i18n tag on the static tag, such as the xlf(xml generated by
<span i18n="@@agDescription"></span>) field format is
<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. Add the i18n attribute to the title For the html tag attribute, you can also add i18n, such as the xlf (xml) format generated by
<span class="delete" i18n-title="@@agDelete" title="删除"></span>is the same as above 3. Translate text without creating elementsWe sometimes have multiple sentence fragments in one sentence. If we add elements such as span and label every time, it may seriously affect the page. Layout, at this time we can use ng-container to wrap the copy that needs to be translated.
<p> <ng-container i18n=@@agLetGo>让我们现在开始吧!</ng-container>朋友! </p>is displayed on the page as
<p> <!----> LET'S GO朋友! </p>* ng-container becomes a comment block, which will not affect the page layout (especially when style is applied) After tagging, we only need to execute ng xi18n to automatically create an xlf file, usually message.xlf. If you need to customize it, you can go to the Angular CLI official website to view it.
XLF and JSON conversion
xlf to json methodI personally use the xml2js library to operate, the simple code is as follows: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 to xlf method
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; }In this way, the extraction of copy information and conversion of the translated file are completed. Next, we need to apply the translated copy to the project.
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 file and modify it to
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)); });Don’t forget to add the locale directory to .angular-cli.json to separate it Pack. In this way, our translation of static copy has basically been completed, but how should we translate some dynamic copy such as copy in ts files or third-party frame attributes? The following will introduce the solution for dynamic copy translation for ts files and the NG-ZORRO framework.
{ "app": { "base": { "hello": "文件文案", "userCount": "一共%num%人" } } }The format has been determined, we continue to define the Service processing methodThe internationalization solution of NG-ZORRO is reused here, which can simplify our development. If you are interested, you can refer to its source code.
*** 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; } }In this way, you only need to call the translate method of Service in Pipe
*** 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); } }Okay, now that our processing logic is completely over, let’s introduce how to use it
*** 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'); } }The above process can basically meet the internationalization needs of most angular projects. If more complex internationalization is needed, please feel free to discuss it. SummaryThe internationalization of Angular to 5.0 has been relatively simple. We only need to tag i18n in the appropriate place to easily and quickly extract the copy that needs to be translated. How to do it specifically? Processing translated files varies from person to person, and multiple methods can help us convert (such as this article through nodejs).
What is more complicated is the text that cannot be translated by typing i18n tags. NG-ZORRO’s internationalization solution makes up for the shortcomings in this aspect. Together, it can easily complete the internationalization of the project. If there is no dedicated team support for internationalization, translation will be very difficult, and there are many things to consider, such as Traditional Chinese, Macau Traditional Chinese, Taiwan Traditional Chinese, etc., and the grammar is also different.
Reference directory
Angular’s internationalization (i18n) online example
NG-ZORRO Locale Internationalization
The above is what I compiled for everyone Yes, I hope it will be helpful to everyone in the future.
Related articles:
How to implement form validation using JQuery, what should be done specifically?
How to set multiple Classes using Vue
How to get the value of the multi-select box value in post in SpringMVC (code example)
jQuery Checkbox selection and value passing example in SpringMVC_jquery
The above is the detailed content of How to implement internationalization using Angular (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!