Translation into Spanish of an interesting article by Philippe Martin, a French software engineer working for Red Hat.
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:
La aplicación descrita está disponible en: https://github.com/feloy/angular-cli-i18n-sample
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 xlf
archivo con las cadenas traducibles. Podemos generar el archivo src/i18n/messages.xlf
con 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.xlf
copiado 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:4200
y verás que efectivamente muestra la cadena en español!
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
, en
o 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.
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.json
para 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.
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.json
para 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"
}
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>
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_ID
token.
Así es como puede obtener el LOCALE_ID
valor 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 >
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 build
comando 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.js
que 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.js
y webpack.fr.config.js
, y luego adaptar estos archivos específicos para cada idioma específico. Aquí está el resultado de un diff
despué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 build
para generar los tres paquetes en dist/enn
, dist/es
y dist/fr
.
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!