(en suite à la question de Zappada sur les multiples BDD)
Principe
On stocke les textes de traduction ("localization") dans un fichier XML, qui sera ensuite compilé en PHP pour accélérer l'affichage des pages.
La traduction (recherche du bon texte pour la langue choisie par l'utilisateur) se fait coté serveur.
Langages utilisés:
XML pour stocker les textes bruts.
PHP pour la traduction coté serveur, oujavascript/XMLHttpRequest pour la traduction coté client.
Description
Dans mon cas, j'ai utilisé un système très similaire [à celui d'avoir des textes dans la BDD, appelés par une fonction + argument unique au texte à traduire], mais plus performant, car il ne requiert pas d'appeler la BDD:
XML
Ce fichier XML est donc composé d'un noeud principal, "localized", avec comme attribut le nom de projet.
Il contient ensuite des sous-noeuds regroupant les typages des traductions ("stream" pour les flux, "html" pour le flux de sortie html vers le client, aka la page web). Ensuite, on a des noeuds ("n") de traduction, possédant un nom "attribut "name", ce qui permettra d'utiliser "getelementsByTagName"). Chaque texte est une balise "t", avec également un nom.
Le texte peut contenir des text-nodes (traduction), et des noeuds conditionnels ("if") dont le contenu-texte n'est affiché que si la condition est remplie. Ce système permet de faire des accords (pluriel) ou des cas particulier ("vous n'avez pas de message"/"vous avez de nouveaux messages).
Ce fichier xml traduit tout le site (ou tout un bout de site) pour UNE langue donnée.
PHP
Ce fichier est ensuite compilé en php pour accélérer les traitements. SI la traduction se fait coté client, la compilation est inutile.
Principe
On stocke les textes de traduction ("localization") dans un fichier XML, qui sera ensuite compilé en PHP pour accélérer l'affichage des pages.
La traduction (recherche du bon texte pour la langue choisie par l'utilisateur) se fait coté serveur.
Langages utilisés:
XML pour stocker les textes bruts.
PHP pour la traduction coté serveur, oujavascript/XMLHttpRequest pour la traduction coté client.
Description
Dans mon cas, j'ai utilisé un système très similaire [à celui d'avoir des textes dans la BDD, appelés par une fonction + argument unique au texte à traduire], mais plus performant, car il ne requiert pas d'appeler la BDD:
XML
Code :
<?xml version="1.0" encoding="utf-8"?>
<localization lang="fr" project="reinom">
<stream>
<html>
<n name="generic">
<t name="description">La plateforme Reinom rassemble des jeux par navigateur et des services web sur un seul portail pour une facilité d'utilisation accrue.</t>
<t name="title">Reinom - Jeux et services web</t>
<t name="keywords">Reinom, plateforme, jeux, service web</t>
<t name="author">Xenos (Vincent MONIER)</t>
</n>
<n name="headingbar">
<n name="title">
<t name="reinom">Liste des jeux et services webs disponibles.</t>
<t name="news">Fil d'actualité de la communauté.</t>
<t name="members">Les membres de la communauté Reinom.</t>
<t name="money">Toutes les informations financières sur Reinom sont publiques: consultez-les.</t>
<t name="contacts">Contactez un membre de l'équipe Reinom.</t>
<t name="requests">Si vous rencontrez un problème avec la plateforme, venez le signaler ici.</t>
<t name="messages" params="new_messages messages">
<if conditions="$0 EQ 0 and $1 EQ 0">Vous n'avez aucun message.</if>
<if conditions="$0 EQ 0 and $1 EQ 1">Vous n'avez aucun nouveau message et 1 message déjà lu.</if>
<if conditions="$0 EQ 0 and $1 GT 1">Vous n'avez aucun nouveau message et $1 messages déjà lus.</if>
<if conditions="$0 EQ 1 and $1 EQ 0">Vous avez 1 nouveau message.</if>
<if conditions="$0 EQ 1 and $1 EQ 1">Vous avez 1 nouveau message et 1 message déjà lu.</if>
<if conditions="$0 EQ 1 and $1 GT 1">Vous avez 1 nouveau message et $1 messages déjà lus.</if>
<if conditions="$0 GT 1 and $1 EQ 0">Vous avez $0 nouveaux messages.</if>
<if conditions="$0 GT 1 and $1 EQ 1">Vous avez $0 nouveaux messages.</if>
<if conditions="$0 GT 1 and $1 GT 1">Vous avez $0 nouveaux messages.</if>
</t>
</n>
<n name="alt">
<t name="reinom">Reinom.</t>
<t name="news">Actualités.</t>
<t name="members">Membres.</t>
<t name="money">Financement.</t>
</n>
</n>
</html>
</stream>
</localization>
Ce fichier XML est donc composé d'un noeud principal, "localized", avec comme attribut le nom de projet.
Il contient ensuite des sous-noeuds regroupant les typages des traductions ("stream" pour les flux, "html" pour le flux de sortie html vers le client, aka la page web). Ensuite, on a des noeuds ("n") de traduction, possédant un nom "attribut "name", ce qui permettra d'utiliser "getelementsByTagName"). Chaque texte est une balise "t", avec également un nom.
Le texte peut contenir des text-nodes (traduction), et des noeuds conditionnels ("if") dont le contenu-texte n'est affiché que si la condition est remplie. Ce système permet de faire des accords (pluriel) ou des cas particulier ("vous n'avez pas de message"/"vous avez de nouveaux messages).
Ce fichier xml traduit tout le site (ou tout un bout de site) pour UNE langue donnée.
PHP
Ce fichier est ensuite compilé en php pour accélérer les traitements. SI la traduction se fait coté client, la compilation est inutile.
Code PHP :
<?php
namespace localized\fr\reinom\stream\html\generic
{
const description='La plateforme Reinom rassemble des jeux par navigateur et des services web sur un seul portail pour une facilité d\'utilisation accrue.';
const title='Reinom - Jeux et services web';
const keywords='Reinom, plateforme, jeux, service web';
const author='Xenos (Vincent MONIER)';
}
namespace localized\fr\reinom\stream\html\headingbar
{
}
namespace localized\fr\reinom\stream\html\headingbar\title
{
const reinom='Liste des jeux et services webs disponibles.';
const news='Fil d\'actualité de la communauté.';
const members='Les membres de la communauté Reinom.';
const money='Toutes les informations financières sur Reinom sont publiques: consultez-les.';
const contacts='Contactez un membre de l\'équipe Reinom.';
const requests='Si vous rencontrez un problème avec la plateforme, venez le signaler ici.';
const register='Inscrivez-vous sur Reinom.';
const login='Connexion.';
const events='Votre fil d\'actualités personnelles.';
const logout='Déconnexion.';
const preferences='Modifiez les paramètres de votre compte.';
}
Le "namespace" est issu du balisage XML. Le nom de chaque constante est issu du nom de la balise "t".
Pour l'utiliser, il me suffit d'appeler la constante qui va bien (localized\fr\reinom\stream\html\headingbar\title\news par exemple). Je n'ai pas encore trouvé de beau moyen pour récupérer les conditions (balises "if").
Javascript
Si on veut traduire coté client et non coté serveur, on peut utiliser XMLHttpRequest pour récupérer le fichier XML (en cache ou non). Une fois récupéré, il faut avoir une liste, dans la page web, des emplacements des textes à traduire, avec le chemin xml du texte. A partir de ces 3 informations (emplacement html, chemin xml, fichier xml), le javascript peut traduire la page coté client. Si on change de langue, il suffit de re-charger le xml.
Avantages:
- Flexibilité (ma propre norme)
- Portabilité (XML; je peux déporter le calcul vers le client plutôt que sur le serveur)
- Ajout possible de langues
- Possibilité de mixer les langues (prendre le texte français en 1er, sinon l'anglais, sinon l'allemand etc)
- Possibilité d'ajouter facilement des langues/textes
- Symétrie totale des langues (il n'y a pas une langue prépondérante, ce que j'aurai eu si j'avais utilisé le français comme langue de base pour le traduire ensuite)
- Possibilité d'ajout des balises de votes/appréciation des différentes traductions pour que les utilisateurs puissent voter pour/contre une traduction
- Possibilité d'avoir plusieurs traductions d'un même texte dans un seul fichier XML (plusieurs noeuds "t" avec le même "name", mais des dates de créations, attribut "date", différentes)
- La compilation XML=>PHP est réalisable via un simple fichier XSL
Avenir
Je normaliserai ce principe sur le site de Reinom, avec les outils qu'il faut pour l'utiliser (type open-source): le XSLD/DTD du document XML, le fichier de compilation XML vers PHP, le principe d'utilisation en PHP, le singleton PHP pour la traduction (et sa doc générique, hors langage), ainsi que les pistes pour la traduction coté client ainsi que ses avantages/inconvénients.
Message édité
Ajout de l'avantage "La compilation XML=>PHP est réalisable via un simple fichier XSL": puisque le fichier-source est en XML, le compilateur peut être réalisé dans le langage XSL, qui a l'atout d'être portable, plutôt rapide, normalisé et implémenté dans de nombreux autres langages (il existe des fonctions déjà faites pour appliquer un XSL à un fichier XML que ce soit en JAVA, en PHP, en javascript, en C/C++ ou en tout un tas d'autres langages usuels)