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.
Background
- ##Angular: 5.0
- Angular Cli: 1.6.1(1.5.x Also available)
- NG-ZORRO: 0.6.8
Angular i18n
i18n template The translation process has four stages:- Mark the static text information that needs to be translated in the component template (that is, add the i18n tag).
- Angular's i18n tool extracts the tagged information into an industry-standard translation source file (such as an .xlf file, using ng xi18n).
- The translator edits the file, translates the extracted text information into the target language, and returns the file to you (translator access is required. This article uses converting xlf files to json format file output, and finally convert the json file back to xlf format file).
- The Angular compiler imports the translated file, replaces the original information with the translated text, and generates a new target language version of the application.
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 id="Angular-nbsp-国际化项目">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.
Deploy translation files
Create a locale folder in the src directory, and save the translated demo.en-US.xlf file in the changed directoryCreate a new i18n-providers.ts in the app folderimport { 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.
ts file copywriting and NG-ZORRO framework copywriting translation
Specific ideasCall the Service method through Pipe and match json according to the corresponding unique id value The translation results in the object are then returned to the front-end for rendering, referring to the international implementation plan of the NG-ZORRO framework. First we define the format of the json translation object, which is a three-layer structure. Dynamic variables need to be wrapped by %%. The reason for this is that it is related to the project structure and also facilitates the unification of the format with i18n later.{ "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!

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Dreamweaver CS6
Visual web development tools

Atom editor mac version download
The most popular open source editor

Zend Studio 13.0.1
Powerful PHP integrated development environment

SublimeText3 Mac version
God-level code editing software (SublimeText3)

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software