C贸mo internacionalizar una aplicaci贸n Angular con angular-cli

Translation into Spanish of an interesting article by Philippe Martin, a French software engineer working for Red Hat.

ANGULARinternationalizationtranslation into spanish
15 April, 2022 Translate an Angular app using angular-cli
15 April, 2022 Translate an Angular app using angular-cli

A translation by Chema, a Spanish translator specializing in technical English to Spanish translations

An original text written by Philippe Martin, originally published in
https://feloy.medium.com/deploying-an-i18n-angular-app-with-angular-cli-fc788f17e358

* * *

Existe una revisi贸n m谩s reciente de este art铆culo publicada en: https://dev.to/angular/deploying-an-i18n-angular-app-with-angular-cli-2fb9

Explicar茅 en este art铆culo c贸mo crear desde cero una aplicaci贸n Angular internacionalizada (i18n) mediante angular-cli, y c贸mo implementarla en un servidor web Apache.

Utilizaremos:

  • angular/cli: 1.0.0
  • angular: 4.0.0
  • apache 2.4

La aplicaci贸n descrita est谩 disponible en: https://github.com/feloy/angular-cli-i18n-sample

Una nueva aplicaci贸n i18n

Primero creamos una nueva aplicaci贸n Angular con la ayuda de angular-cli:

$ ng nuevo angular-cli-i18n-muestra

Realizamos algunos cambios para agregar texto traducible, en app.component.html:

<h1 i18n > 隆Hola, mundo! </h1>

Ahora necesitamos crear un xlfarchivo con las cadenas traducibles. Podemos generar el archivo src/i18n/messages.xlfcon el siguiente comando:

$ ng xi18n --output-path src/i18n

Ahora creamos traducciones para diferentes idiomas, aqu铆 en ingl茅s con un archivo nuevo src/i18n/messages.en.xlfcopiado de src/i18n/messages.xlf:

[...] 
<trans-unit id="[...]" datatype="html">
<source>隆Hola mundo!</source>
<target>隆Hola mundo!</target>
</trans-unit>
[...]

en franc茅s con src/i18n/messages.fr.xlf:

[...] 
<trans-unit id="[...]" datatype="html">
<source>隆Hola mundo!</source>
<target>Salut la foule!</target>
</trans-unit >
[...]

y en espa帽ol con src/i18n/messages.es.xlf:

[...] 
<trans-unit id="[...]" datatype="html">
<source>隆Hola Mundo!</source>
<target>驴hola, qu茅 tal?</target>
</trans -unidad>
[...]

Ahora angular-cli puede servir la aplicaci贸n con el idioma elegido, aqu铆 por ejemplo en espa帽ol:

$ ng servir --aot \ 
--i18n-file=src/i18n/messages.es.xlf \
--locale=es \
--i18n-format=xlf

隆Accede a la aplicaci贸n en http://localhost:4200y ver谩s que efectivamente muestra la cadena en espa帽ol!

Preparaci贸n de la aplicaci贸n para producci贸n

En producci贸n, nos gustar铆a que la aplicaci贸n estuviera ordenada en diferentes subdirectorios, seg煤n el idioma; por ejemplo, la versi贸n en espa帽ol estar铆a accesible en http://myapp.com/es/y la francesa en聽http://myapp.com/fr/.聽Tambi茅n nos gustar铆a contar con una redirecci贸n desde la url base http://myapp.com/a la url del idioma escogido.

Para esto necesitamos cambiar el href base a es,聽eno聽fr, seg煤n el idioma de destino. Pero angular-cli tiene una opci贸n de l铆nea de comando especial para esto, --bh,que permite declarar el href base en el momento de la compilaci贸n desde la l铆nea de comandos.

Usuarios de Linux/macOS

Aqu铆 est谩 el comando Shell que podemos usar para crear los diferentes paquetes de los diferentes idiomas:

$ para lang en es en fr; hacer \ 
ng build --output-path=dist/$lang \
--aot \
-prod \
--bh /$lang/ \
--i18n-file=src/i18n/messages.$lang.xlf \
--i18n -formato=xlf \
--locale=$idioma; \
hecho

Podemos crear una definici贸n de script package.jsonpara este comando y ejecutarlo con npm run build-i18n:

{ 
[...]
"scripts": {
[...]
"build-i18n": " for lang in en es fr; do ng build --output-path=dist/$lang --aot -prod -- bh /$lang/ --i18n-file=src/i18n/messages.$lang.xlf --i18n-format=xlf --locale=$lang; done "
}
[...]
}

En este punto tenemos tres directorios en/, es/ y fr/ en el directorio dist/, que contiene los diferentes paquetes.

Usuarios de Windows

Como usuario de Windows, puedes usar estos comandos para crear los diferentes paquetes para cada idioma:

> ng build --output-path=dist/fr --aot -prod --bh /fr/ --i18n-file=src/i18n/messages.fr.xlf --i18n-format=xlf --locale=fr

> ng build --output-path=dist/es --aot -prod --bh /es/ --i18n-file=src/i18n/messages.es.xlf --i18n-format=xlf --locale=es

> ng build --output-path=dist/en --aot -prod --bh /en/ --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf --locale=en

Podemos crear definiciones de script package.jsonpara estos comandos y una adicional para ejecutar todos estos comandos a la vez y ejecutar el 煤ltimo con npm run build-i18n:

"scripts": { 
"build-i18n:fr": "ng build --output-path=dist/fr --aot -prod --bh /fr/ --i18n-file=src/i18n/messages.fr. xlf --i18n-format=xlf --locale=fr",
"build-i18n:es": "ng build --output-path=dist/es --aot -prod --bh /es/ --i18n- file=src/i18n/messages.es.xlf --i18n-format=xlf --locale=es",
"build-i18n:en": "ng build --output-path=dist/en --aot -prod --bh /en/ --i18n-file=src/i18n/messages.en.xlf --i18n-format=xlf --locale=en",
"build-i18n": "npm run build-i18n:en && npm ejecuta build-i18n:es && npm ejecuta build-i18n:fr"
}

Configuraci贸n en Apache2

Aqu铆 hay una configuraci贸n de host virtual que servir谩 los diferentes paquetes desde el directorio /var/: deber谩s copiar all铆 los tres directorios en/, es/ y fr/ generados anteriormente.

Con esta configuraci贸n, la url聽http://www.myapp.redirige al subdirectorio del idioma preferido definido en la configuraci贸n de su navegador (o lleva al idioma por defecto –en-,si no se encuentra un idioma preferido) y a煤n tiene acceso a los otros idiomas accediendo a los otros subdirectorios.

<VirtualHost *:80> 
ServerName www.myapp.com
DocumentRoot /var/www
<Directorio "/var/www">
RewriteEngine en
RewriteBase / Regla de reescritura ^../index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (..) $1/index.html [L] RewriteCond %{HTTP:Accept-Language} ^fr [NC]
RewriteRule ^$ /fr/ [R] RewriteCond %{HTTP:Accept-Language} ^es [NC]
RewriteRule ^$ /es/ [R] RewriteCond %{HTTP:Accept-Language} !^es [NC]
RewriteCond %{HTTP:Accept-Language} !^fr [NC]
RewriteRule ^$ /en/ [R]
</Directory>
</VirtualHost>

Bonus 1: enlaces a los diferentes idiomas

Ser铆a interesante tener algunos enlaces en la aplicaci贸n para que el usuario pueda navegar a otros idiomas. Los enlaces apuntar谩n a /en/,聽/es/y聽/fr/.

Un dato 煤til: el idioma actual est谩 disponible en el LOCALE_IDtoken.

As铆 es como puede obtener el LOCALE_IDvalor y mostrar la lista de idiomas, diferenciando el idioma actual:

// aplicaci贸n.componente.ts

importar { Componente, LOCALE_ID, Inyectar } desde ' @angular/core ';

@Component ({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

exportar clase AppComponent {
idiomas = [
{ c贸digo: 'en', etiqueta: 'English'},
{ c贸digo: 'es', etiqueta: 'Espa帽ol'},
{ c贸digo: 'fr', etiqueta: 'Fran莽ais'}
];
constructor( @Inject (LOCALE_ID) protegido localeId: cadena) {}
}

<!-- aplicaci贸n.componente.html --><h1 i18n>隆Hola, mundo!</h1>
<template ngFor let-lang [ngForOf]="languages">
<span *ngIf="lang.code !== localeId">
<a href="/{{lang. c贸digo}}/">{{lang.label}}</a> </span>
<span *ngIf="lang.code === localeId">{{lang.label}} </span>
</template >

Bonus 2: i18n despu茅s de la expulsi贸n

Desde angular-cli es posible exportar una configuraci贸n de paquete web para un idioma en particular. Aqu铆 est谩 el comando para exportar la configuraci贸n del paquete web para el idioma ingl茅s. Ten en cuenta que el comando es muy similar al comando ng buildcomando utilizado anteriormente:

ng eject \ 
--output-path=dist/en \
--aot \
-prod \
--bh /en/ \
--i18n-file=src/i18n/messages.en.xlf \
--i18n-format=xlf \
--locale=es

Este comando crear谩 un archivo webpack.config.jsque se usar谩 para construir la versi贸n en ingl茅s cuando se ejecute el comando npm run build.

Ahora puedes copiar este archivo webpack.config.en 3 archivos distintos para los 3 idiomas diferentes, por ejemplo webpack.en.config.js,聽webpack.es.config.jsy聽webpack.fr.config.js, y luego adaptar estos archivos espec铆ficos para cada idioma espec铆fico. Aqu铆 est谩 el resultado de un diffdespu茅s de los cambios requeridos para el idioma franc茅s:

--- webpack.config.js 
+++ webpack.fr.config.js
@@ -44,7 +44,7 @@
]
},
"salida": {
- "ruta": ruta.join(proceso.cwd (), "dist/ en "),
+ "ruta": ruta.join(proceso.cwd(), "dist/ fr "),
"nombre de archivo": "[nombre].[chunkhash:20].bundle.js ",
"chunkFilename": "[id].[chunkhash:20].chunk.js"
},
@@ -220,7 +220,7 @@
}
}),
nuevo BaseHrefWebpackPlugin({
- "baseHref": "/ en /"
+ "baseHref": "/ fr /"
}),
nuevo CommonsChunkPlugin({
"nombre": "en l铆nea",
@@ -283,9 +283,9 @@
new AotPlugin({
"tsConfigPath": "src/tsconfig.json",
"mainPath": "main.ts",
- "i18nFile": "src/i18n/messages. en .xlf",
+ "i18nFile": "src/i18n/messages. fr .xlf",
"i18nFormat": "xlf",
- "locale": " en ",
+ "locale": " fr ",
"hostReplacementPaths ": {
"entornos/entorno.ts": "entornos/entorno.prod.ts"
},

Tambi茅n debes modificar el archivopackage.para que el comando ejecute el webpack de cada configuraci贸n:

{ 
[...]
"scripts": {
[...]
"construir": "webpack --config webpack.fr.config.js && webpack --config webpack.en.config.js && webpack --config webpack .es.config.js"
}
[...]
}

Ahora puedes ejecutar npm run buildpara generar los tres paquetes en dist/enn,聽dist/esy聽dist/fr.

Bonus 3: aplicaci贸n de traductor angular

Este fin de semana para AngularAttack 2017, he creado una aplicaci贸n que definitivamente puede ayudar a traducir aplicaciones Angular. Todav铆a est谩 en desarrollo, cualquier comentario ser谩 bienvenidos: http://angular-translator.elol.fr/聽.

隆Buenas traducciones!

Valora este art铆culo