Una manera fácil de agregar varios idiomas a su sitio

Introduccion


Como parte de mi proyecto, me enfrenté a la tarea de hacer que el sitio web actual de la empresa fuera multilingüe. Más precisamente: para crear la capacidad de traducir rápida y fácilmente el sitio al inglés, polaco, italiano, etc.

Una búsqueda en Internet mostró que las opciones existentes para crear un sitio multilingüe son extremadamente voluminosas e ineficientes. Conectar bibliotecas de terceros a menudo es problemático, y los consejos para escribir su solución están asociados con una gran cantidad de trabajo del mismo tipo.

Escribir un método alternativo para cambiar la configuración regional me llevó solo unas pocas horas, y mantener la unidad semántica minimiza por completo los cambios al agregar nuevas páginas.

Los archivos fuente para el sitio de muestra con traducción automática se pueden descargar en github

Alternativas existentes


Cuando la tarea recién apareció en el desarrollo, el primer paso, por supuesto, fue estudiar soluciones y consejos ya preparados en los foros sobre cómo implementar de manera más fácil y correcta la posibilidad de cambiar la configuración regional. Los recursos de Internet más populares para crear sitios multilingües ofrecen las siguientes soluciones:

  • Crear bloques html duplicados con texto en diferentes idiomas, de los cuales solo uno queda activo para el usuario, y el resto están ocultos (pantalla: ninguno).

    La desventaja obvia de este método es el aumento increíblemente rápido del código y una pérdida instantánea de legibilidad y facilidad de mantenimiento del código. Además, esta solución es vulnerable a errores en el texto y la escalabilidad en términos de aumentar el número de idiomas (en lo sucesivo denominados locales).
  • Conectar un servicio de traducción automática de terceros (como google translate) con muchos idiomas incorporados y cambios mínimos en el código fuente de la página.

    Cuando la tarea apareció por primera vez en la lista de tareas, utilizamos este método como el más obvio y conveniente, sin embargo, la experiencia de trabajar con hablantes nativos de los Estados Unidos e Israel mostró que la traducción automática a menudo comete errores al cambiar la configuración regional, y los usuarios del sitio reaccionan muy bruscamente a tales errores de traducción Al final, los socios estratégicos aconsejaron encarecidamente cambiar el método de cambiar la ubicación, y este método tuvo que ser abandonado.
  • Cambiar el idioma utilizando las capacidades de js o bibliotecas / marcos de terceros como jQuery, basado en la búsqueda y el cambio directo de elementos DOM.

    Una característica de este enfoque es la búsqueda de una gran cantidad de selectores js, cuyo texto debe reemplazarse. Este enfoque puede funcionar bien para proyectos pequeños, pero con un aumento en el número de páginas, el número de funciones de reemplazo de texto aumenta proporcionalmente, lo que conduce a una pérdida de eficiencia en proyectos grandes.

Solución alternativa


La base del enfoque que propongo, como alternativa a los métodos existentes, es, curiosamente, no la base escrita por mi código js, ​​que generalmente es trivial, y el diseño de selectores, cuyo soporte le permite configurar de manera flexible y fácil la traducción de cualquier número de páginas a cualquier idioma sin cambios en la base del código y duplicación excesiva de datos.

Al cambiar la configuración regional con un enfoque alternativo, se distinguen tres jugadores principales:

  • página html con la regla establecida para selectores de bloque con texto
  • servicio js general, cuya tarea principal es reemplazar los elementos DOM de textContet de acuerdo con la regla de diseño de los selectores
  • Archivo JSON de configuración regional que contiene una estructura que contiene bloques html en todos los idiomas utilizados al cambiar la configuración regional

El cumplimiento de las reglas de diseño para los selectores de elementos mutables elimina la necesidad de cambiar el código js del servicio de cambio de configuración regional, que es una gran ventaja en términos de escalabilidad del proyecto.

La regla para construir selectores


La mayoría de los métodos para cambiar la configuración regional de la página (entre las alternativas 1.3 y parcialmente 2) sugieren que necesita "marcar" el bloque html variable de alguna manera, ya que es correcto cambiando el campo de clase. El mismo mecanismo utiliza una opción alternativa.

El primer paso en el diseño de selectores es dividir la página de origen en bloques de funciones de nivel superior. En la página de nuestra empresa hay bloques:
Le damos a cada bloque un nombre condicional, por ejemplo,

  • Menu

  • Tarjeta de visita (hogar)

  • Ejemplo de operación de servicio (ejemplo)

  • Socios (clientes)

  • Alcance del servicio (userfulBlock)

  • Ejemplos del servicio (ejemplos)

  • Contactos y comentarios (contactos)


Ejemplo de sitio web
Ejemplo de sitio web

Después de eso, dividimos cada bloque en bloques funcionales más pequeños, como se hace con la biblioteca React.

Ejemplo de sitio web
Ejemplo de sitio web

Asignamos nuestros nombres a las áreas seleccionadas y obtenemos una estructura del formulario:

  • menu

  • inicio principal, descripción, botones

  • estadísticas de ejemplo , título, descripción, botones

  • botones de clientes

  • titular de userfulBlock, userfulCards, elseBlock

  • ejemplos de titulares, tarjetas

  • titular de contactos , descripción, contactos, formulario


Continuamos este procedimiento hasta llegar a los bloques que contienen el texto fuente.

Como resultado, obtenemos una estructura de archivo JSON de configuración regional lista para usar que contiene todos los textos necesarios para cambiar el idioma. Además, según este algoritmo, se determina la regla para construir selectores:

Cada selector comienza con la palabra clave de configuración regional y luego, de acuerdo con el estilo de mayúsculas y minúsculas, se agregan los nombres de todos los bloques principales, incluido el bloque que contiene el texto de origen, por ejemplo, la descripción de ejemplo en la primera tarjeta tendrá el selector de descripción de ubicación-ejemplo-tarjetas

Ejemplo de sitio web
Ejemplo de sitio web

Se puede ver un ejemplo del archivo json de configuración regional resultante en github

Servicio de cambio de local


El servicio de cambio de configuración regional es un módulo que contiene la función de cargar un archivo de configuración regional

loadLocale(defLang) 

con el parámetro opcional defLang: el idioma establecido después de cargar la configuración regional (idioma predeterminado), así como la función principal de cambiar la configuración regional actual

 changeLocale(lang) 

indicando el idioma requerido.

Función de descarga local


La función de carga de configuración regional utiliza la solicitud XMLHttpRequest estándar de datos. El uso de este estándar se debe al deseo de minimizar el número de dependencias y la facilidad de uso de la solicitud. Después de recibir el archivo de configuración regional, se muestra una notificación sobre la recepción de datos en la consola, y se llama a la función de cambiar la configuración regional al idioma predeterminado si este idioma se pasó a la función como un parámetro opcional. Puede familiarizarse con el código de función aquí:

 function loadLocale(defLang) { var xhr = new XMLHttpRequest(); xhr.open("GET", 'http://localhost:3000/locale.json', true); xhr.onreadystatechange = saveLocale.bind(this); xhr.onerror = function () { console.log("no found page"); }; xhr.send(); function saveLocale() { if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) { locale = JSON.parse(xhr.responseText); console.log("locale loaded"); if(defLang) changeLocale(defLang); } } } 

Función de cambio de configuración regional


Tipos de datos


Es una función recursiva cuya tarea principal es atravesar el objeto que contiene la configuración regional de la página (usando el algoritmo DFS). El uso de la recursividad en la construcción de una función le permite codificar el algoritmo de la manera más simple y concisa posible, sin embargo, demasiada profundidad de recursión puede provocar un desbordamiento de la pila. Las funciones para solucionar este problema se pueden encontrar en el foro del mismo nombre o leyendo los artículos relevantes en habr.com.

La función recursiva se basa en el procesamiento de 4 tipos de datos:

  • campo que contiene una cadena de texto fuente utilizada para agregar a la página.
    Por ejemplo:

     "main": "    " 

  • campo que contiene una matriz de líneas de texto fuente utilizado para agregar a
    página Este campo es necesario para crear listas cuyos elementos se pueden cambiar.
    orden Por ejemplo:

     "menu":["Home","Example","Clients","Info","Contacts"] 

  • Estructura de datos anidados que contiene su propio conjunto de campos necesarios para construir
    Arquitectura de la página. Por ejemplo:

      "home": { "main": "selling quest from your video", "description": "for social networks & sites", "buttons": ["try","order"] } 

  • Una matriz de estructuras de datos anidados, con el mismo conjunto de campos utilizados. Tal
    las matrices se usan cuando aparecen listas de bloques de código idénticos, por ejemplo,
    tarjetas de miembros del equipo, cartera o tarifas por los servicios prestados.
    Por ejemplo:

      "usefulCards": [ { "headline": "Marketers and agencies", "statistics": ["convers 26%", "retent 25%"], "button": "ORDER" }, { "headline": "Production studios and TV platforms", "statistics": ["convers 24%", "retent 33%"], "button": "ORDER" }, { "headline": "Conference creators", "statistics": ["convers 65%", "retent 15%"], "button": "ORDER" }, { "headline": "Bloggers and streamers", "statistics": ["convers 24%", "retent 33%"], "button": "ORDER" } ], 

    En un sitio, podría verse así:

    Ejemplo de sitio web
    Ejemplo de sitio web


Funciones de procesamiento


El procesamiento del tipo de datos fuente se realiza mediante una función separada

 function getText(key, object, name,startIndex) 

El nombre del campo de entrada del campo de estructura con el texto de origen, el objeto de configuración regional actual que contiene el texto que se va a agregar y el nombre del selector actual requerido para buscar el elemento DOM.

 function getText(key, object, name, startIndex) { var elementKey=0; if(startIndex) elementKey = startIndex; for ( ; elementKey < document.getElementsByClassName(name + "-" + key).length; elementKey++) if (!isNaN(elementKey)) document.getElementsByClassName(name + "-" + key)[elementKey].textContent = object[key]; } 

El procesamiento de una matriz de cadenas con texto fuente también se lleva a cabo mediante una función separada

 function getArrayText(key, object, name,startIndex) 

La firma y el cuerpo de esta función no son diferentes del pasado, excepto que los elementos de la matriz se asignan a los elementos DOM.

 function getArrayText(key, object, name, startIndex) { var elementKey=0; if(startIndex) elementKey = startIndex; for ( ; elementKey < document.getElementsByClassName(name + "-" + key).length; elementKey++) if (!isNaN(elementKey)) document.getElementsByClassName(name + "-" + key)[elementKey].textContent = object[key][elementKey % object[key].length]; } 

La función recursiva principal para reemplazar texto trata con la clasificación del campo de localización actual en uno de los 4 tipos anteriores y la reacción correspondiente al tipo resultante:

 function changeText(name, object, startIndex) { for (key in object) if (Array.isArray(object[key]) && typeof object[key] != 'string' && typeof object[key][0] == 'string') getArrayText(key, object, name); else if (typeof object[key] == "object" ){ if(isNaN(key)) changeText(name + "-" + key, object[key]); else changeText(name, object[key],key); } else getText(key, object, name, startIndex); } 

Esta función acepta la configuración regional de idioma actual y el selector raíz (en este caso, "configuración regional"). Además, al detectar una estructura anidada o una matriz de estructuras, la función se llamará recursivamente a sí misma, cambiando los parámetros de entrada en consecuencia.

La principal ventaja del enfoque alternativo es que el servicio descrito anteriormente no requiere ningún cambio funcional y se agrega como un archivo js utilizando el archivo de configuración regional que creó.

Conclusión


La esencia del enfoque descrito anteriormente es una regla fija para describir los selectores y construir un archivo de configuración regional. Gracias a esto, existe una oportunidad única para traducir cualquier página fuera de la caja y reutilizar material ya traducido.

El algoritmo para construir los selectores descritos anteriormente no es obligatorio y crítico para el servicio. El servicio es flexible para expandir y agregar nuevos métodos y algoritmos, así como para construir nombres de selector y estructuras locales de json. Una posible ventaja sería guardar la configuración regional en la cookie del navegador y cambiar la configuración regional, dependiendo de la ubicación del usuario del servicio.

Los archivos de origen para el sitio de muestra con traducción automática se pueden descargar en github .

Source: https://habr.com/ru/post/437124/


All Articles