Mejores prácticas para la localización y globalización de cadenas y etiquetas [cerrado]

124

Soy miembro de un equipo con más de 20 desarrolladores. Cada desarrollador trabaja en un módulo separado (algo cerca de 10 módulos). En cada módulo podríamos tener al menos 50 formularios CRUD, lo que significa que actualmente tenemos cerca de 500 botones de agregar , guardar , editar , etc.

Sin embargo, debido a que queremos globalizar nuestra aplicación, necesitamos poder traducir textos en nuestra aplicación. Por ejemplo, en todas partes, la palabra complemento debe convertirse en ajouter para los usuarios franceses.

Lo que hemos hecho hasta ahora es que para cada vista en UI o capa de presentación, tenemos un diccionario de pares de traducciones clave / valor. Luego, mientras renderizamos la vista, traducimos los textos y cadenas requeridos usando este diccionario. Sin embargo, este enfoque, hemos llegado a tener algo cerca de 500 complemento en 500 diccionarios. Esto significa que hemos violado al director DRY.

Por otro lado, si centralizamos cadenas comunes, como poner add en un lugar y pedimos a los desarrolladores que lo usen en todas partes, nos encontramos con el problema de no estar seguros de si una cadena ya está definida en el diccionario centralizado o no.

Otra opción podría ser no tener un diccionario de traducción y usar servicios de traducción en línea como Google Translate, Bing Translator, etc.

Otro problema que hemos encontrado es que algunos desarrolladores bajo el estrés de entregar el proyecto a tiempo no pueden recordar las claves de traducción . Por ejemplo, para el texto del botón Agregar, un desarrollador ha usado agregar mientras otro desarrollador ha usado nuevo , etc.

¿Cuál es la mejor práctica o el método más conocido para la globalización y localización de los recursos de cadena de una aplicación?

Mouneer
fuente
2
La charla de Alex Sexton sobre el tema La internacionalización del lado del cliente de la conferencia JS EU es un buen comienzo.
Minko Gechev

Respuestas:

51

Hasta donde sé, hay una buena biblioteca llamada localeplanetLocalización e Internacionalización en JavaScript. Además, creo que es nativo y no depende de otras bibliotecas (por ejemplo, jQuery)

Aquí está el sitio web de la biblioteca: http://www.localeplanet.com/

También mire este artículo de Mozilla, puede encontrar muy buenos métodos y algoritmos para la traducción del lado del cliente: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with- a-little-help-from-json-and-the-server /

La parte común de todos esos artículos / bibliotecas es que usan una i18nclase y un getmétodo (de alguna manera también definen un nombre de función más pequeño _) para recuperar / convertir el keya value. En mi explicación de la keycadena de medios que desea traducir y la valuecadena de medios traducida.
Luego, solo necesita un documento JSON para almacenar key's y value' s.

Por ejemplo:

var _ = document.webL10n.get;
alert(_('test'));

Y aquí el JSON:

{ test: "blah blah" }

Creo que usar las soluciones actuales de bibliotecas populares es un buen enfoque.

Afshin Mehrabani
fuente
1
Sin ofender, pero ¿no es esto lo que ya intentó Afshin? Su problema es que diferentes desarrolladores tienen dificultades para recordar qué teclas usar. Estoy de acuerdo con que su método descrito es el camino a seguir. No veo cómo puede ser de otra manera. Gracias por los excelentes enlaces por cierto.
Spock
47

Cuando se enfrenta a un problema por resolver (y, francamente, ¿quién no lo es en estos días?), La estrategia básica que usualmente usamos los informáticos se llama "divide y vencerás". Dice así:

  • Conceptualice el problema específico como un conjunto de subproblemas más pequeños.
  • Resuelve cada problema más pequeño.
  • Combine los resultados en una solución del problema específico.

Pero "divide y vencerás" no es la única estrategia posible. También podemos adoptar un enfoque más generalista:

  • Conceptualice el problema específico como un caso especial de un problema más general.
  • De alguna manera resuelve el problema general.
  • Adapte la solución del problema general al problema específico.

- Eric Lippert

Creo que ya existen muchas soluciones para este problema en lenguajes del lado del servidor como ASP.Net/C#.

He esbozado algunos de los principales aspectos del problema.

  • Problema : necesitamos cargar datos solo para el idioma deseado

    Solución : para este fin, guardamos los datos en archivos separados para cada idioma

ex. res.de.js, res.fr.js, res.en.js, res.js (para el idioma predeterminado)

  • Problema: los archivos de recursos para cada página deben estar separados para que solo obtengamos los datos que necesitamos

    Solución : Podemos usar algunas herramientas que ya existen como https://github.com/rgrove/lazyload

  • Problema: necesitamos una estructura de pares clave / valor para guardar nuestros datos

    Solución : sugiero un objeto javascript en lugar de string / string air. Podemos beneficiarnos de la inteligencia de un IDE

  • Problema: los miembros generales deben almacenarse en un archivo público y todas las páginas deben acceder a ellos

    Solución : para este propósito, creo una carpeta en la raíz de la aplicación web llamada Global_Resources y una carpeta para almacenar el archivo global para cada subcarpeta que llamamos 'Local_Resources'

  • Problema: cada miembro de subsistemas / subcarpetas / módulos debe anular a los miembros de Global_Resources en su alcance

    Solución : consideré un archivo para cada

Estructura de la aplicación

root/
    Global_Resources/
        default.js
        default.fr.js
    UserManagementSystem/
        Local_Resources/
            default.js
            default.fr.js
            createUser.js
        Login.htm
        CreateUser.htm

El código correspondiente para los archivos:

Global_Resources / default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};

Global_Resources / default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};

El archivo de recursos para el idioma deseado debe cargarse en la página seleccionada de Global_Resource: este debe ser el primer archivo que se carga en todas las páginas.

UserManagementSystem / Local_Resources / default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";

UserManagementSystem / Local_Resources / default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";

UserManagementSystem / Local_Resources / createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 

UserManagementSystem / Local_Resources / createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";

archivo manager.js (este archivo debe cargarse al final)

res.lang = "fr";

var globalResourcePath = "Global_Resources";
var resourceFiles = [];

var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;

if(!IsFileExist(currentFile))
    currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");

resourceFiles.push(currentFile);

// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
    currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";

    if(!IsExist(currentFile))
        currentFile = folder + "\\Local_Resource\\default.js";
    if(!IsExist(currentFile)) throw new Exception("File Not Found");

    resourceFiles.push(currentFile);
}

for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }

// Get current page name
var pageNameWithoutExtension = "SomePage";

currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;

if(!IsExist(currentFile))
    currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");

Espero eso ayude :)

Omid Shariati
fuente
77
Lo único que no me gusta de este enfoque es que la localización y el desarrollo están estrechamente vinculados ... Entonces, cuando se agrega una cadena en inglés (lo que sea predeterminado), el resto de los idiomas deben actualizarse a través del código. Prefiero tener JSON creado con una herramienta de algún tipo de archivo de traducción. Sigue siendo una buena representación!
Nate-Wilkins
hecho de la misma manera que lo hizo para la localización, puede ver eso en esta consulta: stackoverflow.com/q/53864279/4061006 . ¿Lo único es cómo está traduciendo Global_Resources / default.js a Global_Resources / default.fr.js? ¿Qué herramienta / kit está utilizando para convertir esos archivos a los idiomas deseados? Como yo también necesito esto
Jayavel
Debería almacenar un comentario legible por humanos junto a cada tecla que describa a dónde va la cadena y lo que significa, de modo que pueda proporcionar más contexto al traductor (oa usted mismo) cuando vaya a agregar un nuevo idioma y haya olvidado qué de las cuerdas significan. Haga algo como "Create" : {"message": "Create", "description": "text on the button that opens the editor with a blank Foo"}lo hacen para localizar extensiones de Chrome, por ejemplo. O cree un archivo separado que contenga estos comentarios.
Boris
13

jQuery.i18n es un complemento ligero de jQuery para permitir la internacionalización en sus páginas web. Le permite empaquetar cadenas de recursos personalizadas en archivos '.properties', al igual que en los paquetes de recursos de Java. Carga y analiza paquetes de recursos (.properties) según el idioma proporcionado o el idioma informado por el navegador.

para saber más sobre esto, eche un vistazo a ¿Cómo internacionalizar sus páginas con JQuery?

BalaKrishnan 웃
fuente
El enlace se ha ido
Alexander Farber