Agregue soporte multilingüe a Angular

Agregue soporte multilingüe a Angular

En este tutorial, lo guiaremos a través del proceso para hacer que su aplicación sea accesible y fácil de usar para personas de todo el mundo. Solo alrededor del 20 por ciento del mundo habla inglés, por lo que proporcionar otras opciones de idioma puede mejorar su experiencia de usuario y aumentar considerablemente el alcance de su aplicación. Vamos a echar un vistazo a las herramientas de internacionalización integradas de Angular y le mostraremos cómo usarlas correctamente.

Hemos creado una aplicación de demostración muy sencilla para demostrar el proceso. Clona desde aquí y luego siga las instrucciones de instalación.

Inicie la aplicación para familiarizarse con ella. Simplemente muestra y actualiza números y valores aleatorios con diferentes contextos, p. Ej. monedas, fechas, etc. Cubriremos algunos de los canales y características que se utilizan durante el tutorial.



01. Términos clave para los idiomas de apoyo

Agregue soporte multilingüe a Angular: introducción

Si su sitio está solo en inglés, se está perdiendo una gran audiencia

Hay dos palabras que a menudo se usan indistintamente cuando se habla de traducir una aplicación, internacionalización y localización, sin embargo, en realidad significan cosas ligeramente diferentes. La internacionalización se refiere al proceso de preparación de su aplicación para admitir diferentes idiomas. Por el contrario, la localización se refiere al proceso de traducir su aplicación a los idiomas requeridos. Básicamente, la internacionalización es algo que se hace una vez por aplicación, y la localización se realiza una vez por ubicación, al menos ese es el plan.

Estos términos también pueden resultar familiares en sus versiones abreviadas: i18n (donde 18 es el número de letras entre la primera 'i' y la última 'n' de internacionalización) y l10n (donde 10 es el número de letras entre la 'i' y la 'n' de localización).

02. ¿Qué es la localización?

En la actualidad, se utilizan más de 6.000 idiomas en todo el mundo, la mayoría de los cuales solo lo utilizan grupos muy pequeños de personas. Sin embargo, incluso si solo nos enfocamos en los tres idiomas principales, mandarín, español e inglés, habrá diferencias significativas en el formato de fecha, estructura gramatical, pluralización y formato de números.

Si incluimos el quinto idioma más utilizado, el árabe, encontramos otra diferencia; El árabe es un script de derecha a izquierda (RTL), lo que significa que la interfaz de usuario también tendrá que reflejarse.

Así que durante la localización tenemos que considerar las diferencias de gramática, diseño y formato y, por supuesto, también tenemos que cambiar el texto en sí. Angular puede ayudar con gran parte de esto, pero aún deberá traducir el texto manualmente.

03. Locales en Angular

Necesitaremos localizar para cada configuración regional que necesitemos admitir. Un lugar se refiere al conjunto general de preferencias por las consideraciones mencionadas anteriormente que tienden a compartirse dentro de una región del mundo, generalmente un país. Cada configuración regional está representada por un identificador de configuración regional Unicode, que especifica el código de idioma y la extensión de la configuración regional.

La configuración regional predeterminada de Angular es 'en-US', que es el código de idioma 'en' (inglés) como se habla en la región 'US' (Estados Unidos de América). Una aplicación localizada para 'en-US' será sutilmente diferente de una aplicación localizada para 'en-GB', que es el inglés que se habla en Gran Bretaña. Por ejemplo, en los EE. UU., Las fechas tienen un formato (desconcertantemente) mm / dd / aaaa, mientras que aquí en el Reino Unido utilizamos el enfoque más sensato de dd / mm / aaaa. Esta pequeña diferencia puede resultar en un gran error de comprensión.

Para hacer las cosas interesantes, localicemos nuestra aplicación de demostración para árabe como se habla en Irak, también conocido como 'ar-IQ' e inglés como se habla en el Reino Unido, también conocido como 'en-GB'. Usaremos el inglés como predeterminado esta vez.

04. Construir configuración

Nuestro proyecto de demostración se creó utilizando Angular CLI, que incluye algunas herramientas útiles. Vamos a utilizar el compilador Ahead-of-Time (AOT) para este proyecto, por lo que debemos realizar algunos cambios en el archivo de configuración de la CLI: 'angular.json'. Si desea utilizar Just-in-Time (JIT), debe configurar las cosas de manera ligeramente diferente.

Con una compilación AOT, obtiene una aplicación lista para usar de renderizado pequeña y más rápida que se carga sin la necesidad de solicitudes asincrónicas para obtener elementos como plantillas y hojas de estilo. Como resultado, debe crear una compilación para cada configuración regional y entregar la compilación adecuada utilizando la URL o algún tipo de lógica de detección de idioma del lado del servidor. El enfoque más simple es crear un directorio para cada configuración regional, p. Ej. www.example.com/en-GB y www.example.com/ar-IQ. La compensación es que no puede cambiar de idioma sobre la marcha, pero en realidad es poco probable que sea algo que requieran los usuarios reales.

En primer lugar, debemos agregar una configuración de compilación para nuestra configuración regional árabe. En el archivo JSON, busque el objeto 'architect.build.configurations'. Agregue el siguiente bloque para definir una configuración para la configuración regional:

cómo pintar un cielo azul con acrílicos
|_+_|

Esta configuración le dice a Angular dónde generar la compilación compilada y qué archivo de traducción y formato usar. También establece la configuración regional y le dice a Angular en qué directorio se implementará la aplicación.

También necesitamos modificar las opciones predeterminadas en 'architect.build.options' para usar la configuración regional 'en-GB'. Establezca las siguientes propiedades como se muestra. Tenga en cuenta que estamos habilitando AOT aquí en todos los ámbitos, por lo que se usará para compilaciones de producción y desarrollo:

|_+_|

Angular admite varias configuraciones regionales. Asegúrese de utilizar el valor correcto para la propiedad 'i18nLocale'. Puedes ver la lista completa aquí .

Detrás de escena, las configuraciones anteriores simplemente cargan y leen desde uno de estos archivos de preferencias de configuración regional.

05. Configuración de servicio

Además de configurar la salida de la compilación, también necesitamos configurar la configuración del comando 'ng serve' para el desarrollo. Esto es más sencillo ya que simplemente podemos hacer referencia a la configuración de compilación que acabamos de agregar. En 'angular.json' agregue el siguiente bloque a 'architect.serve.configurations':

|_+_|

Aquí nos referimos a las opciones de configuración de compilación usando la propiedad 'browserTarget', y también estamos configurando el 'servePath'. Antes de que podamos servir o construir la aplicación árabe, necesitamos crear el archivo de traducciones al que se hace referencia en la propiedad 'i18nFile' anterior. Angular CLI incluye una herramienta para extraer texto marcado en un archivo fuente de traducción estándar de la industria.

Cubriremos estos archivos con más detalle más adelante en el tutorial, pero por ahora solo necesitamos exportar el archivo vacío básico para permitirnos compilar.

Usaremos el comando 'ng xi18n' con las siguientes opciones. Esta es la única vez que incluiremos el ID de la configuración regional en el nombre de archivo '--out-file':

|_+_|

Esto debería crear un archivo en un directorio src / locale. De ahora en adelante, siempre mostraremos el archivo llamado 'messages.xlf' y lo copiaremos manualmente sobre la versión con el ID de configuración regional en el nombre. La razón de esto es evitar que la herramienta de extracción sobrescriba cualquier traducción existente que hayamos agregado al archivo.

06. Configuración del interruptor

Agregue soporte multilingüe a Angular: configuración de conmutación

Al cambiar la configuración, puede utilizar de forma predeterminada las monedas específicas de la ubicación

En este punto, ahora podemos compilar el proyecto y ver qué sucede, pero necesitamos decirle al comando 'ng serve' qué configuración usar. Primero echemos un vistazo a la versión en inglés. No hay cambios aquí porque el inglés es el predeterminado:

|_+_|

Como puede ver, se parece mucho a la versión original, que usa la configuración regional predeterminada de Angular de 'en-US'. La diferencia notable es que la moneda ahora especifica US $ en lugar de solo $. Bien, ahora probemos la versión árabe. Detenga la versión en inglés y ejecute:

|_+_|

Como era de esperar, hay diferencias más obvias en esta versión, en particular, la fecha ahora está escrita en árabe. Angular puede hacer esto porque los nombres de algunas cosas, como meses y días, provienen de una lista establecida y, en última instancia, se relacionan con un número conocido. Todo lo demás, sin embargo, todavía está en inglés.

07. Tuberías conscientes de la configuración regional

Eche un vistazo más de cerca al código fuente de 'app.component.html' y verá que usamos varios canales diferentes. Las siguientes tuberías angulares son compatibles con la configuración regional, lo que significa que adaptan su salida en función de la configuración regional actual: 'DatePipe', 'CurrencyPipe', 'DecimalPipe' y 'PercentPipe'.

Si usa estas tuberías con cuidado, Angular se encargará de gran parte del trabajo de localización por usted. Con cuidado nos referimos a utilizar las opciones predefinidas disponibles siempre que pueda. Un buen ejemplo es el formato de fecha de EE. UU. Frente al Reino Unido que mencionamos anteriormente. Si se encuentra en el Reino Unido y desea mostrar una fecha utilizando el formato (sensato) día-mes-año, es posible que se sienta frustrado al descubrir que la opción predefinida '' shortDate '' se representa como m / d / aa (p. Ej. 9/10/18) y tenga la tentación de codificar el formato deseado de esta manera:

|_+_|

Pero ahora sabemos que obtenemos el formato m / d / aa porque Angular usa la configuración regional 'en-US' por defecto. Entonces, en lugar de codificar el formato, deberíamos usar la opción '' shortDate '' y localizar nuestra aplicación para usar 'en-GB'.

|_+_|

Se necesita un poco más de esfuerzo, pero luego podemos agregar configuraciones regionales al contenido de nuestro corazón y siempre tener un formato de fecha fácil de usar.

08. Anulación de las opciones predefinidas

Desafortunadamente, no parece que exista una forma fácil e integrada de anular un formato predefinido. Por ejemplo, no puede simplemente decidir que prefiere que el formato '' shortDate '' sea dd / mm / aaaa en lugar de dd / mm / y ya que no hay forma de modificar el formato en tiempo de ejecución. Además, no puede agregar sus propias opciones predefinidas.

Para estos casos extremos, puede crear una tubería de fecha personalizada que envuelva el 'DatePipe' angular y maneje cualquier formato personalizado por configuración regional. Todo lo que no reconozca se pasará al 'DatePipe' integrado.

09. CurrencyPipe

Fuera del estante, el 'CurrencyPipe' formateará un número como dólares estadounidenses, lo recortará a dos lugares decimales y agregará agrupaciones como se define en las preferencias de la configuración regional.

Notará que en nuestras dos regiones la moneda siempre está en dólares estadounidenses. No cambia mágicamente a Sterling (GBP) cuando usa la configuración regional 'en-GB'. La razón de esto es que £ 10 no es lo mismo que $ 10, por lo que debe especificar explícitamente la moneda a la que se refiere su número.

almacenamiento de icloud lleno pero no

Actualicemos 'app.component.html' para usar GBP en todo momento. Al especificar el código de moneda, debe utilizar el valor correcto del estándar ISO 4217 (lista disponible en línea).

Modifique las dos tuberías de divisas agregando ':' GBP '' así:

|_+_|

Y comenzará a ver el símbolo £ en lugar de US $.

Recuerde, no hace nada inteligente como convertir automáticamente USD al valor equivalente en GBP si cambia la moneda, solo cambia el símbolo que usa.

10. Flujo de trabajo de traducción

Bien, tenemos nuestras dos configuraciones regionales configuradas y Angular nos está ayudando a hacer parte del trabajo de inmediato, pero el texto todavía está en inglés. Angular no puede traducir esto automáticamente, lamentablemente, pero puede ayudarnos con partes del flujo de trabajo. Esto es lo que tiene que suceder:

  • Marcar texto estático en todos los componentes para su traducción
  • Exportar archivo de traducción que contiene este texto estático
  • Modifique el archivo de traducción y agregue las traducciones relevantes
  • Fusionar el archivo de traducción traducido nuevamente en la aplicación

Angular nos ayuda con los pasos 2 y 4, pero como desarrolladores debemos hacer el paso 1 manualmente. El paso 3 normalmente lo completará un profesional o una agencia de traducción, utilizando un software especial para leer y actualizar el archivo de traducción.

11. Detalles del eje

Para lograr esto tenemos que agregar un atributo especial a cada elemento que contenga texto fijo a traducir. Para que quede claro si el contenido proviene de una API, entonces ese no es texto fijo y deberá localizarlo en la API. Solo necesita agregar el atributo cuando el texto está escrito directamente en la plantilla HTML en su código fuente. Un punto clave aquí es que debe tratar de mantener sus archivos TypeScript independientes de la configuración regional; en otras palabras, evite poner cualquier texto que deba traducirse en la lógica del componente y manténgalo todo en las plantillas. De lo contrario, la herramienta de extracción no podrá extraerlo. De todos modos, es una buena práctica separar sus preocupaciones, en la vida y en el código.

Abramos 'app.component.html' y comencemos con el título 'Valor actual'. Simplemente agregue el atributo 'i18n' al elemento que contiene directamente el texto.

|_+_|

Es importante comprender que esto es solo un atributo personalizado 'tonto'. No es una directiva Angular que desencadena nada en tiempo de ejecución, de hecho, el compilador lo elimina después de la traducción.

De todos modos, veamos qué sucede cuando volvemos a ejecutar la herramienta de extracción para regenerar el archivo de traducción. Recuerde que '--out-file' es solo 'messages.xlf' ahora:

|_+_|

Abra el archivo XLF de salida y debería ver un nuevo bloque de unidad de traducción que se parece a esto con información de contexto adicional:

|_+_|

Genial, eso significa que la herramienta recogió el atributo 'i18n'. Esa ID larga es generada por la herramienta y permanecerá igual a menos que cambie el texto. Si tiene varias instancias de exactamente el mismo texto, todas obtendrán el mismo ID. ¡No edite este ID!

Si lo prefiere, puede especificar un ID personalizado dentro del atributo 'i18n'. Si hace esto, la identificación seguirá siendo la misma incluso si el texto cambia, por lo que debe asegurarse de que no haya colisiones de identificación en toda la aplicación. Utilice el prefijo '@@' para establecer una identificación personalizada. Aquí la identificación se convertirá en 'título':

|_+_|

12. Agrega algo de contexto

Para asegurarse de que el traductor pueda proporcionar una traducción precisa, a menudo necesitará conocer el contexto en el que se está utilizando el texto. El atributo 'i18n' nos permite definir una descripción y un significado para ayudar al traductor. El formato es el siguiente:

|_+_|

Actualicemos nuestro título con un significado y una descripción:

|_+_|

Eso debería darle al traductor suficiente contexto para proporcionar una traducción precisa. Regenere el archivo de traducción y debería ver que estos valores se han generado. Vale la pena señalar que si no utiliza una identificación personalizada, la identificación generada tiene en cuenta el significado y el texto. Entonces, el mismo texto, pero con un significado diferente, obtendrá una ID diferente. Sin embargo, la descripción no tiene ningún impacto en la identificación.

13. Texto con variables

Pasemos a la sección de introducción. El primer párrafo contiene texto y una variable que se interpolará en tiempo de ejecución. Como manejamos esto?

Bueno, felizmente, es bastante sencillo. Nuevamente, necesitamos agregar un atributo 'i18n' significativo al elemento contenedor. Agréguelo directamente al elemento de párrafo:

|_+_|

Vea cómo se ha detallado la interpolación de variables en la salida. Lo bueno de esto es que permite al traductor modificar la estructura gramatical de la oración si es necesario, sin romper la encuadernación. Por ejemplo, puede haber un idioma en el que la oración se escribiría mejor: el valor X era el cierre de ayer, es decir, con la variable al principio.

14. Pluralización

Pasando al siguiente párrafo, verá una sintaxis intimidante. Esto se denomina formato de mensaje de ICU y le permite especificar diferentes fragmentos de texto en función del valor de una variable.

Puede usar esto para agregar la 's' a las palabras en inglés cuando el valor es cero o no uno. Por ejemplo, si 'segundos' es una variable que contiene el número de segundos, podemos usar esta expresión de pluralización de UCI:

|_+_|

Que dará como resultado:

  • 0 segundos
  • 1 segundo
  • 2 segundos

No parece estar documentado, pero también puede usar 'AsyncPipe' dentro de la sintaxis de pluralización para trabajar con Observables.

En ese ejemplo, 'uno' y 'otro' son categorías de pluralización. Hay varias categorías para elegir, ¡pero cuidado! No todas las configuraciones regionales admiten todas las categorías, y Angular no le dice si intenta usar una categoría que no es compatible con la configuración regional actual. Es fácil terminar pensando que ha hecho algo mal porque la categoría 'dos' no funciona en su configuración regional 'en-GB' y, en cambio, está viendo el texto 'otro'. Inexplicablemente, 'en' (y muchos otros lenguajes comunes) solo admiten 'uno' y 'otro', aunque 'cero' y 'dos' son valores explícitos.

Mira este archivo para ver qué es realmente compatible.

15. Los gráficos de barras radiales múltiples

Podemos solucionar esta limitación utilizando números en lugar de categorías. Simplemente prefija el valor con un '=':

|_+_|

Esto ya está configurado en la aplicación de demostración, solo necesitamos agregar el atributo 'i18n' al párrafo que lo contiene:

|_+_|

Ejecute la herramienta de extracción nuevamente para ver cómo se ve. Verá que esto se emite de manera ligeramente diferente. Creará dos unidades de traducción; uno para la expresión ICU en sí y otro que interpola esa expresión en la cadena original.

16. Seleccionar expresión

Si desea mostrar un texto diferente según el valor de una variable, puede usar una expresión ICU 'seleccionar' que es muy similar a la sintaxis 'plural' mostrada anteriormente. En nuestra aplicación de demostración, monitoreamos el cambio aplicado al valor y creamos un flujo observable llamado 'tendencia $' que genera 'hacia arriba', 'hacia abajo' o 'estable' dependiendo de si el cambio es positivo, negativo o cero.

Luego, conectamos nuestra expresión ICU 'select' para generar una cadena diferente según el valor de la transmisión. Aquí puede ver el 'AsyncPipe' en uso:

|_+_|

Esta es una sintaxis algo más limpia que usar 'ngIf' o 'ngSwitch' para manipular el DOM, además de que también funciona bien con la herramienta de extracción. Agregue el atributo 'i18n' al elemento contenedor:

|_+_|

Regenere el archivo de traducciones y verá que el enfoque es similar a la salida plural, con dos unidades de traducción creadas. Las expresiones ICU son bastante útiles una vez que te acostumbras a ellas, además puedes anidarlas para crear salidas más complejas.

17. Agregar traducciones

Agregue soporte multilingüe a Angular: marcado

Una vez que haya marcado todo el texto que necesita traducir, puede generar un archivo de traducción

Un atributo 'i18n' más para agregar:

|_+_|

Ahora que hemos marcado todo el texto que necesita traducción, podemos generar el archivo de traducción por última vez. Una vez creado, cámbiele el nombre a 'messages.ar-IQ.xlf' y reemplace la encarnación anterior. Este es el archivo que le enviaremos al profesional de la traducción, pero para los propósitos de este tutorial, ¡Google Translate estará presente!

Abra el archivo XLF y duplique cada '' elemento, renombrándolo ''. Desafortunadamente, puede estar bastante desordenado, por lo que podría ayudar a embellecer el contenido.

Para comprobar que los tenemos todos, guarde el archivo e inicie la aplicación con la configuración regional árabe:

|_+_|

Si ve algún mensaje en la terminal como este, significa que se ha perdido uno:

|_+_|

Con suerte, no tendrá ningún error y podrá ver la aplicación en el navegador. Todavía no hemos agregado ningún árabe real, por lo que no se verá muy diferente.

18. Traductor de Google

Agregue soporte multilingüe a Angular: Google Translate

cómo hacer que el álbum sea privado en facebook
Google Translate es una forma fácil de crear traducciones para su sitio

Comencemos con algo fácil: el título 'Valor actual'. Google Translate me dice que debería ser (texto en árabe aquí), así que actualice el valor en el elemento '':

|_+_|

Hasta ahora tan bueno. Ahora hagamos uno con interpolación. Aquí está 'El valor de cierre de ayer fue ...' (¡con suerte!):

|_+_|

Utilice un número cuando traduzca para que pueda ver dónde debería estar la interpolación. Tenga en cuenta que cuando vea el resultado traducido en Google Translate, aparecerá invertido, es decir, el número al principio, pero cuando lo copie y pegue en el archivo de traducción, volverá al orden original. Esto sucede porque el árabe es un idioma RTL, por lo que el script está (casi) completamente reflejado. Google Translate hace esto agregando un atributo 'dir =' rtl '' al elemento contenedor. Aprenderemos cómo hacer esto en el siguiente paso. El resto de las traducciones están disponibles en el repositorio de demostración, rama 'tutorial'.

19. Dirección de guión

Necesitamos administrar la dirección del script en nuestra aplicación porque Angular no lo hará automáticamente por nosotros. Tampoco parece haber ninguna forma de detectar si la configuración regional actual es un lenguaje LTR o RTL, por lo que tendremos que codificar esto. Sería genial si Angular ofreciera una directiva incorporada para esto.

Abra 'app.component.ts'. Importe 'Inject', 'LOCALE_ID' y 'HostBinding' desde '' @ angular / core ''. Luego configure el 'HostBinding' de la siguiente manera. Esto agregará un atributo 'dir' al AppComponent y establecerá la dirección de idioma predeterminada en 'ltr':

|_+_|

Luego agregue un constructor e inyecte el 'LOCALE_ID'. Recuerde que esto lo establece nuestra configuración porque estamos usando AOT.

|_+_|

Y finalmente agregue el siguiente fragmento al método 'ngOnInit' existente. Aquí estamos verificando si 'LOCALE_ID', es decir, 'ar-IQ', comienza con 'ar' y si cambia la dirección a 'rtl' en su lugar.

|_+_|

Sin embargo, si planea admitir más configuraciones regionales, probablemente necesite refactorizar esto para hacerlo más escalable, ya que solo hay unos diez lenguajes RTL en uso hoy en día, este enfoque no debería ser demasiado difícil de manejar. Inicie la aplicación árabe y ahora debería ver que la interfaz de usuario está reflejada: el signo £ debe estar a la derecha.

20. Producción

El paso final es generar y verificar nuestras construcciones de producción. Primero, sin embargo, necesitamos hacer otra modificación rápida a la configuración 'angular.json'.

En 'architect.build.configurations' duplique el objeto de producción existente y cámbiele el nombre a '' production-ar-IQ ''. Luego copie y pegue las propiedades de la configuración '' ar-IQ '' existente en el objeto, para que tenga tanto las opciones de producción como las opciones 'i18n'.

También necesita actualizar 'architect.serve.configurations'. Esta vez, duplique el objeto '' ar-IQ '' existente y cámbiele el nombre a '' production-ar-IQ '' y cambie el valor de 'browserTarget' para apuntar a su nueva configuración 'production-ar-IQ'.

Ahora puede construir y servir su configuración regional árabe de producción con este comando:

|_+_|

¡Bien, hemos terminado! Hemos internacionalizado con éxito nuestra aplicación y la hemos localizado para audiencias 'en-GB' y 'ar-IQ'. Angular hace que el proceso sea notablemente sencillo para el desarrollador, de hecho, lo más difícil es averiguar cuáles deberían ser las traducciones: ¡disculpas a los hablantes de árabe si algo está mal!

Este artículo se publicó originalmente en el número 281 de la revista de diseño web creativo Web Designer. Compra el número 281 aquí o suscríbete a Web Designer aquí .

Artículos relacionados: