MISE À JOUR 2 : En fait, j'ai fini par utiliser cela, et c'est génial après quelques ajustements. Voici mon article sur sa conception actuelle et en action: http://tim.hithlonde.com/2013/lemon-schema-works/
Je crée une application Web et je veux qu'elle prenne en charge plusieurs langues. Cette structure a deux composantes:
- Connexion des paramètres régionaux ('anglais', 'Deutch', etc.) avec des termes, et ayant une pierre de rosette connectant les termes et les termes dans une langue spécifique.
- Regroupement des termes par page. Je ne veux pas dire, SELECT term1, term2, etc. à travers les 30+ termes dont je pourrais avoir besoin sur une page. Je veux demander par la page à laquelle ils sont connectés.
Voici ma structure de table proposée (notez que tous les id ont des relations / index entre eux pour faire des requêtes très efficaces):
* locale
* id
* value //English, Deutch, etc//
* terms
* id
* value //In English//
* page
* id
* value //Think add entry, menu//
* page_group //group all terms to a page, for easy pulling//
* id
* page.id
* term.id
* rosetta
* id
* locale.id
* term.id
* value //french word for amount, description, etc//
Cela permettra des requêtes comme:
SELECT localization.value,
terms.value
FROM localization
INNER JOIN terms ON terms.id=localization.termid
INNER JOIN page_group ON page_group.termid=localization.termid
INNER JOIN page ON page.id=page_group.pageid
INNER JOIN locale ON locale.id=localization.localeid
WHERE page.value='add_entry' AND locale.id=custlangid
ORDER BY terms.id
Je n'ai qu'à demander deux articles; l'ID de langue dont j'ai besoin et la page dont j'ai besoin. Il servira tous les termes, dans la langue spécifiée, qui font partie du groupe de termes de cette page.
Je pense que c'est une très bonne structure, mais j'aimerais avoir des commentaires.
MISE À JOUR : Pour clarifier, nous ne parlons que de la localisation des composants de l' interface utilisateur . (étiquettes, navigation, texte utile) Toutes les informations saisies par l'utilisateur seront stockées en unicode, pas dans ce schéma.
MISE À JOUR 2 : J'ai fini par l'utiliser, et c'est génial. Voici mon article sur son design actuel et en action: http://tim.hithlonde.com/2013/lemon-schema-works/
la source
<?php echo $term['term_in_english'];?>
Je m'efforce d'une solide approche MVC.Réponses:
Nous avons fait beaucoup de cela, et les utilisateurs (administratifs) ont été autorisés à corriger les traductions en direct. (Vous voudrez peut-être toujours une couche de mise en cache, mais je ne veux absolument pas piloter cela avec une vraie base de données et non des fichiers de ressources - cela vous donne une tonne de puissance pour interroger et trouver des choses qui doivent être traduites, etc.). Je pense que votre schéma est probablement très bien, donc je vais juste vous transmettre quelques trucs que nous avons appris dans l'espoir qu'il soit utile.
Une chose que vous avez omise est les phrases avec des points d'insertion. Dans l'exemple ci-dessous, l'ordre est inversé et la langue est toujours l'anglais, mais cela pourrait très facilement être deux langues différentes - faites semblant que ce ne sont que deux langues qui mettent normalement les choses dans un ordre différent.
Dans notre pre-.NET, nous avions une routine qui faisait l'insertion pour que les phrases ressemblent à ceci:
Ce serait évidemment simplement utilisé dans votre code comme
<%= String.Format(phrase, username, points); %>
ou similaireCe qui a un peu aidé le traducteur. Mais .NET String.FOrmat ne prend pas en charge les commentaires dans la chaîne de format, malheureusement.
Comme vous le dites, vous ne voudriez pas gérer cela dans votre php avec une conscience locale ou des méta-phrases.
Donc, ce que nous avions était un tableau de phrases maître:
phraseid, anglais, informations supplémentaires
et une table localisée:
phraseid, localeid, traduction
Vous avez également supposé avec INNER JOINS que les versions localisées existaient - nous avions tendance à les laisser de côté jusqu'à ce qu'elles soient traduites, de sorte que la requête de votre part ne finirait par ne rien retourner au début (pas même la valeur par défaut)
Si une traduction n'existait pas, la nôtre par défaut était l'anglais, puis se repliait sur le code fourni (dans le cas où la base de données n'avait pas l'ID, et il était également clair d'après le code quelle phrase l'identifiant "TXT_LNG_WRNNG_INV_LOW" essayait réellement d'obtenir ) - donc l'équivalent de cette requête est ce que nous avons utilisé:
De toute évidence, vous pourriez obtenir toutes les choses en même temps en utilisant votre système de page.
Nous avions tendance à ne pas lier les choses à la page car elles étaient beaucoup réutilisées entre les pages (et pas seulement dans les fragments de page ou les contrôles), mais c'est très bien.
Dans le cas de nos applications natives Windows, nous avons utilisé la réflexion et un fichier de mappage du contrôle à la balise de traduction afin que la traduction ne nécessite pas de recompilation (dans les applications pré.NET, nous devions baliser les contrôles à l'aide de la balise ou d'une autre spéciale Propriétés). C'est probablement un peu plus problématique en PHP ou ASP.NET MVC, mais possible en ASP.NET où il existe un modèle de page côté serveur complet.
Pour les tests, vous pouvez évidemment rechercher très facilement les traductions manquantes. Pour trouver des endroits qui doivent être étiquetés, traduisez le dictionnaire de phrases entier en utilisant le latin-porc ou le klingon ou quelque chose comme remplacer chaque caractère non-espace par? - l'anglais devrait se démarquer et vous faire savoir que du texte brut nu s'est glissé dans votre HTML.
la source
Les traductions sont généralement effectuées par des sociétés spécialisées externes. En tant que tel, ce serait compliqué de gérer le contenu traduit dans une base de données. Il vaut mieux les gérer dans des "bundles" ou des fichiers de propriétés via une sorte de fonctionnalité linguistique offerte par votre plateforme. Pour y parvenir, dans la base de données, il vous suffit de placer un mnémonique pour la chaîne. Ensuite, en fonction de la langue souhaitée, vous recherchez dans le bundle. par exemple.
la source
getLocalizedContent
. Sauf au niveau du contrôleur, je demanderai tous les termes connectés à une page et la langue dans laquelle je le veux. Cette fonction appellera la requête que j'ai décrite ci-dessus et fera un peu de magie pour que je récupère un tableau associatif, où la clé sera le mnémonique, et la valeur sera le terme. Le nombre de termes d'interface utilisateur sera petit (<100), donc je ne vois pas que ce soit un problème de gestion dans une base de données. Je vais probablement créer une interface simple pour saisir les termes traduits et les pages de regroupement.Créez simplement 3 tables
1.) Maître de langue (LangId, LangName)
2.) Maître des ressources (ResourceMasterId, TableId, ColumnId, ColumnName)
3.) Détails des ressources (ResourceMasterId, LangId, Value)
clé composite (ResourceMasterId, LangId) sur les détails de la ressource
la source