Bonnes pratiques pour la localisation et la globalisation des chaînes et des étiquettes [fermé]


124

Je fais partie d'une équipe de plus de 20 développeurs. Chaque développeur travaille sur un module séparé (environ 10 modules). Dans chaque module, nous pourrions avoir au moins 50 formulaires CRUD, ce qui signifie que nous avons actuellement près de 500 boutons d'ajout , de sauvegarde , de modification , etc.

Cependant, parce que nous voulons globaliser notre application, nous devons pouvoir traduire des textes dans notre application. Par exemple, partout, le mot ajouter devrait devenir ajouter pour les utilisateurs français.

Ce que nous avons fait jusqu'à présent, c'est que pour chaque vue de l'interface utilisateur ou de la couche de présentation, nous avons un dictionnaire de paires clé / valeur de traductions. Ensuite, lors du rendu de la vue, nous traduisons les textes et les chaînes requis à l'aide de ce dictionnaire. Cependant, cette approche, nous en sommes venus à avoir quelque chose près de 500 ajouter dans 500 dictionnaires. Cela signifie que nous avons enfreint le principe DRY.

D'un autre côté, si nous centralisons les chaînes communes, comme mettre add en un seul endroit, et demandons aux développeurs de l'utiliser partout, nous rencontrons le problème de ne pas être sûr si une chaîne est déjà définie dans le dictionnaire centralisé ou non.

Une autre option pourrait être de ne pas avoir de dictionnaire de traduction et d'utiliser des services de traduction en ligne tels que Google Translate, Bing Translator, etc.

Un autre problème que nous avons rencontré est que certains développeurs sous le stress de livrer le projet à temps ne peuvent pas se souvenir des clés de traduction . Par exemple, pour le texte du bouton d'ajout, un développeur a utilisé add tandis qu'un autre développeur a utilisé new , etc.

Quelle est la meilleure pratique ou la méthode la plus connue pour la mondialisation et la localisation des ressources de chaîne d'une application?


2
L' intervention d' Alex Sexton sur le thème de l' internationalisation côté client de la conférence JS EU est un bon début.
Minko Gechev

Réponses:


51

Autant que je sache, il existe une bonne bibliothèque appelée localeplanetLocalisation et Internationalisation en JavaScript. De plus, je pense que c'est natif et n'a pas de dépendances avec d'autres bibliothèques (par exemple jQuery)

Voici le site Web de la bibliothèque: http://www.localeplanet.com/

Regardez aussi cet article de Mozilla, vous pouvez trouver de très bonnes méthodes et algorithmes de traduction côté client: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with- un-peu-d'aide-de-json-et-le-serveur /

La partie commune de tous les articles / bibliothèques est qu'ils utilisent une i18nclasse et une getméthode (à certains égards , définissant également un nom de fonction plus petite comme _) pour récupérer / convertir l' keyau value. Dans mon explication, les keymoyens que la chaîne que vous souhaitez traduire et la valuechaîne traduite signifie.
Ensuite, vous avez juste besoin d'un document JSON pour stocker keyles et value.

Par exemple:

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

Et voici le JSON:

{ test: "blah blah" }

Je pense que l'utilisation des solutions de bibliothèques populaires actuelles est une bonne approche.


1
Aucune offense mais n'est-ce pas ce qu'Afshin a déjà essayé? Son problème est que différents développeurs ont du mal à se souvenir des clés à utiliser. Je suis d'accord avec le fait que votre méthode décrite est la voie à suivre. Je ne vois pas comment il peut en être autrement. Merci pour les excellents liens btw.
Spock

47

Lorsque vous êtes confronté à un problème à résoudre (et franchement, qui n'est pas de nos jours?), La stratégie de base généralement adoptée par nous, informaticiens, s'appelle «diviser pour conquérir». Ça va comme ça:

  • Conceptualisez le problème spécifique comme un ensemble de sous-problèmes plus petits.
  • Résolvez chaque petit problème.
  • Combinez les résultats en une solution du problème spécifique.

Mais «diviser pour conquérir» n'est pas la seule stratégie possible. Nous pouvons également adopter une approche plus généraliste:

  • Conceptualisez le problème spécifique comme un cas particulier d'un problème plus général.
  • Résolvez en quelque sorte le problème général.
  • Adaptez la solution du problème général au problème spécifique.

- Éric Lippert

Je crois que de nombreuses solutions existent déjà pour ce problème dans les langages côté serveur tels que ASP.Net/C#.

J'ai décrit certains des principaux aspects du problème

  • Problème : nous devons charger les données uniquement pour la langue souhaitée

    Solution : à cette fin, nous sauvegardons les données dans des fichiers séparés pour chaque langue

ex. res.de.js, res.fr.js, res.en.js, res.js (pour la langue par défaut)

  • Problème: les fichiers de ressources de chaque page doivent être séparés afin que nous n'obtenions que les données dont nous avons besoin

    Solution : nous pouvons utiliser certains outils qui existent déjà comme https://github.com/rgrove/lazyload

  • Problème: nous avons besoin d'une structure de paires clé / valeur pour enregistrer nos données

    Solution : je suggère un objet javascript au lieu de string / string air. Nous pouvons bénéficier de l'intellisense d'un IDE

  • Problème: les membres généraux doivent être stockés dans un fichier public et toutes les pages doivent y accéder

    Solution : À cet effet, je crée un dossier à la racine de l'application Web appelé Global_Resources et un dossier pour stocker le fichier global pour chaque sous-dossier que nous l'avons nommé 'Local_Resources'

  • Problème: chaque membre de sous-systèmes / sous-dossiers / modules doit remplacer les membres Global_Resources sur leur étendue

    Solution : j'ai considéré un fichier pour chaque

Structure de l'application

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

Le code correspondant pour les fichiers:

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"
};

Le fichier de ressources pour la langue souhaitée doit être chargé sur la page sélectionnée dans Global_Resource - Ce doit être le premier fichier chargé sur toutes les pages.

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";

fichier manager.js (ce fichier doit être chargé en dernier)

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");

J'espère que ça aide :)


7
La seule chose que je n'aime pas dans cette approche est que la localisation et le développement sont étroitement liés ... Ainsi, lorsqu'une chaîne anglaise (quelle que soit la valeur par défaut) est ajoutée, le reste des langues doit être mis à jour via le code. Je préfère créer JSON avec un outil à partir d'un type de fichier de traduction. Encore une bonne représentation!
Nate-Wilkins

avez fait de la même manière que pour la localisation, vous pouvez le voir dans cette requête: stackoverflow.com/q/53864279/4061006 . La seule chose à faire est de savoir comment traduire Global_Resources / default.js en Global_Resources / default.fr.js? Quel outil / kit utilisez-vous pour convertir ces fichiers dans les langues souhaitées. Puisque j'ai besoin de ça aussi
Jayavel

Vous devez stocker un commentaire lisible par l'homme à côté de chaque clé décrivant où va la chaîne et ce qu'elle signifie, afin de pouvoir fournir plus de contexte au traducteur (ou à vous-même) lorsque vous allez ajouter une nouvelle langue et que vous avez oublié ce que certains des cordes signifient. Faites quelque chose comme "Create" : {"message": "Create", "description": "text on the button that opens the editor with a blank Foo"}ils le font pour localiser les extensions Chrome par exemple. Ou créez un fichier séparé contenant ces commentaires.
Boris le

13

jQuery.i18n est un plugin jQuery léger pour permettre l'internationalisation dans vos pages Web. Il vous permet de conditionner des chaînes de ressources personnalisées dans des fichiers «.properties», tout comme dans les ensembles de ressources Java. Il charge et analyse les ensembles de ressources (.properties) en fonction de la langue fournie ou de la langue signalée par le navigateur.

pour en savoir plus, consultez la rubrique Comment internationaliser vos pages avec JQuery?


Le lien est parti
Alexander Farber
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.