Fichier langue [7.1]
2- GnapZ
on May 21 2006 -
Effectivement, c'est un sujet important et délicat. Il y a une discussion en cours là dessus dans les articles International et site multilingue. Rien n'est encore sûr à ce sujet.
3- Gmcms
on May 21 2006 -
- mettre les variables en database
- gérer les traductions avec poedit
- pouvoir connaître à tout moment le niveau d'avancement d'une traduction et avancer doucement tout en ayant un replis sur la langue par défaut pour toute variable non traduite.
Le fichier langue est bien aussi mais il est plus délicat à maintenir pour les traducteurs. Grâce à poedit, chaque mot ou phrase à un identifiant qui lui est propre ce qui permet une traduction fine et dès que quelqu'un a écrit un module le système indique les variables à traduire.
4- GnapZ
on May 21 2006 -
5- Gmcms
on May 22 2006 -
La librairie gettext doit être activée sur l'hébergeur/serveur. Vous pouvez vérifier que gettext est bien installé en faisant un phpinfo (on doit voir gettext enabled) . C'est le cas chez free et chez ovh.
Il faut commencer par sélectionner la langue dans laquelle envoyer les documents au browser, et ensuite appeler un set de fonction pour indiquer à gettext dans quel fichier il va devoir rechercher les chaînes traduites.
Il faut fixer la variable d'environnement LANG à sa valeur correcte. Le format est langue_PAYS; par exemple pour le francais, on aura fr_FR, pour l'anglais en_EN, pour l'américain en_US...
On utilisera pour cela la fonction putenv : putenv("LANG=fr_FR");
Ensuite, appeler setlocale avec comme arguments LC_ALL, et la langue à sélectionner : setlocale(LC_ALL, $language);
Enfin, définir un nouveau "domaine" de langues, et dire à gettext d'utiliser ce domaine. En fait, les fichiers de langues sont situés dans une arborescence bien précise, dont gettext a besoin de savoir le répertoire racine et le nom des fichiers de langue.
On spécifie ces deux derniers avec la fonction bindtextdomain :
$domain = 'messages';
bindtextdomain("$domain","/chemin/vers/le/ repertoire/racine/du/domaine");
textdomain("$domain");
Cela signifie que le nom du fichier de langue source sera messages.po, sa version compilée messages.mo, et qu'il se trouvera dans le domaine dont le répertoire racine sera "/chemin/vers/le/repertoire/racine/du/domaine".
Pour avoir en sortie un codage de caractères différent de celui utilisé par défaut (en général iso-8859-1), changer le nom du charset dans le Content-type du fichier de traduction n'est pas suffisant, il faut utiliser la fonction bind_textdomain_codeset.
Par exemple pour obtenir de l'UTF-8 : bind_textdomain_codeset("$domain", "UTF-8");
Le répertoire racine sera le répertoire spécifié avec bindtextdomain. Commencer par créer dans ce répertoire un dossier nommé "locale". Dans ce répertoire locale, créer un répertoire pour chaque langue, avec pour nom le code de cette langue (par exemple, fr_FR ou en_US...). Dans chacun de ces répertoires, créer un répertoire nommé LC_MESSAGES.
Le fichier de langues est très simplement composé de paires identifiant/traduction. L'identifiant est une chaine de caractères comprise entre des guillements ", précédée par le mot clé "msgid".
De même, une traduction est une chaine de caractères comprise entre des guillemets ", précédée du mot clé "msgstr".
Une paire identifiant/traduction sera par exemple:
msgid "Bienvenue sur ma page personnelle !"
msgstr "Welcome on my Homepage !"
Afin de faciliter la relecture, msgid et msgstr peuvent être définies sur plusieurs lignes. Dans ce cas, il faut indiquer que le message se fera sur plusieurs lignes en mettant la première chaîne à "". On aura donc:
msgid ""
"Voici un message un peu plus long"
" qui tient sur plusieurs lignes"
msgstr ""
"Here is a longer message"
" in several lines"
- Il est courant d'oublier des espaces entre les mots lorsque les chaines sont sur plusieurs lignes.
- Si l'identifiant/traduction doit contenir un ", le précéder d'un \.
Ce fichier de langue devra avoir pour nom le nom spécifié lors de l'appel à bindtextdomain, et avoir pour extension ".po". Il devra se trouver dans le répertoire /chemindevotredomaine/locale/fr_FR/LC_MESSAGES/.
Avant de pouvoir être utilisé, le fichier de langue (.po) doit être compilé (en .mo), pour des raisons de performances avant tout (voir programme poedit pour travailler sur la traduction et la compilation en mode graphique).
Pour faire référence à la traduction correspondant à l'identifiant "Identifiant de chaine", il suffit de faire:
echo gettext("Identifiant de chaine");
Ou encore plus simplement, utiliser le raccourci _() echo _("Identifiant de chaine");
ou bien:
print _("Identifiant de chaine");
On aura dans le fichier de langue :
msgid "Identifiant de chaine"
msgstr "Traduction pour cet identifiant"
echo _("Identifiant de chaine"); affichera "Traduction pour cet identifiant".
Il est préférable de mettre comme identifiant la totalité du texte en anglais. Ainsi, si par malheur gettext ne fonctionnait pas dû à une panne quelconque, le texte en anglais s'afficherait quand même.
Un test de performance a été effectué à cette adresse : suivante
On peut constater que la méthode décrite au dessus est plus performante que l'utilisation de variables tableau. Un bon exemple d'utilisation des méthodes est de récupérer les codes du benchmark : ici
6- Fernand
on May 22 2006 -
Merci, et encore merci...
Bernard est à la fois le leader technique et le fondateur de YACS. C'est lui qui vous répondra explicitement et vous présentera par la même occasion les évolutions possibles sur ce sujet.
Il est actuellement en déplacement, autrement il vous aurait déjà répondu depuis longtemps (c'est la raison pour laquelle je joue ici les standardistes)... J'ai donc envie de dire:Surtout, restez en ligne.
Vous êtes chaleureusement bienvenu parmi nous. (Nous apprécions hautement que vous appréciez YACS).
7- Bernard
on May 22 2006 -
8- Vinc
on May 23 2006 -
En un mot : bravo.
Deux question subsistent :
1. La recherche d’une autre solution que le stockage de texte dans le code est-il admis ?
2. Le texte sorti du code peut-il contenir du PHP à exécuter ?
1. Nous avions échangé en mars des impressions à ce sujet au mois de mars avec Bernard par e-mail. Il m'a convaincu depuis d'utiliser le forum. J'espère qu'il ne m'en voudra donc pas de le citer ici
car ce qu’il dit me paraît toujours juste sur certains points...et éclaire la situation actuelle.
En conséquence de quoi, j' 'avais proposé à Bernard un fichier langues qu'il a placé à l'adresse suivante.
Ce fichier correspond à la version 6.3.1. je ne l'ai pas mis à jour car je ne vois pas à quoi il servirait sans méthode d’utilisation en aval. 
Or, je ne voyais jusqu'à aujourd'hui pas comment l'exploiter, ce que semble proposer merveilleusement Gmcms (?)
. Ce système semblerait en tout cas résoudre le problème de la convivialité du mode d’édition.
2. Il faudra tout de même vérifier que le calcul de la valeur chaîne se fait au moment de son appel sans quoi le php ne pourra pas intégrer, notamment, les skin et les valeurs propres à l'environnement au moment de l'affichage de la page, par exemple, la chaîne suivante :
//EN error.php: 31
$local['text_en'] = Skin::build_block("Check the adress", 'title')
."Normally we are not using upper case letters, and no spacing sign.\n"
.Skin::build_block("Update your bookmark", 'title')
.'It is likely that we have changed the content of this site without warning you.'
.' Thank you for browsing '.Skin::build_link($context['url_to_root'], 'the site front page', 'shortcut').' and to refresh your bookmark.'."\n"
.Skin::build_block("Search this site", 'title')
.'Type one or several words in the searching form. Then hit Enter.'."\n"
.Skin::build_block("Browse shortcuts", 'title')
.'Index of '.Skin::build_link($context['url_to_root'], 'articles', 'shortcut').','
.' '.Skin::build_link($context['url_to_root'], 'files', 'shortcut').' and '.Skin::build_link($context['url_to_root'], 'links', 'shortcut')
.' will show you instantaneously the freshest pages and the most read pages on this site.'
.' This can be an efficient way for you to reach the adequate page.'."\n";
Si j’analyse cette chaîne de caractères, je vois plusieurs difficultés: 
1. la concaténation qui pourrait être contournée par la possibilité d’avoir plusieurs lignes dans le fichier .po
2. les fonctions du type skin ::build_block(…) et skin ::build_link(…)
3. la réutilisation de chaînes plus ou moins récemment calculées telles que $context['url_to_root']
L’ordre des éléments composant une phrase n’est pas toujours le même d’une langue à l’autre. Par conséquent, je suis assez d’accord avec le fait que les traductions fassent partie du code, à moins de se contenter de phrases et d’éléments contextuels moins riches, comme le dit très justement Bernard.
Si effectivement ce genre de difficultés peuvent être contournées par une assignation dynamique de noms de variables (c’est le cas en PHP) et par un appel dynamique de fonctions telles que décrites ci-dessus, alors , je rêve.
Est-ce le cas ?
Si ce n’est pas le cas,
il faudra décortiquer chaque chaîne faisant appel à une fonction PHP et reconstruire ces chaînes préalablement à leur appel.
Je veux bien collaborer à répertorier les lignes de codes à traduire pour les nouvelles versions.
Serait-ce un tournant pour la traduction de ce superbe CMS ?
9- Gmcms
on May 23 2006 -
Cependant, cette méthode est un vrai casse tête pour les traducteurs (comment savoir où sont les nouvelles chaînes à traduire), sans compter le fait qu'il existe de nombreuses redondances de chaînes.
La méthode utilisée dans YACS se rapproche de cette philosophie et de ses défauts avec un problème supplémentaire : il ne respecte pas la "dissociation du codage".
Pour expliquer ce concept de codage, je prendrais un exemple plus connu que la partie serveur : la partie cliente (browser).
On peut caricaturer la partie cliente en :
- une structure
- un style
- un comportement
La structure est donnée par le xhtml, le style est donné par le css et le comprtement est donné par le javascript. Or une bonne façon de coder en gardant à l'esprit que dans une équipe ce n'est pas forcément la même personne qui fait ces 3 thèmes, c'est de ne pas mettre de style dans le code xhtml mais le sortir dans un fichhier css et de ne pas mettre de javascript dans le code xhtml mais d'appliquer des comprtements aux tags css. De plus l'avantage de ce dernier c'est que la page fonctionne par défaut sur les browsers sans javascript (handicapés ou mobiles).
Il en est de même pour la partie serveur. En toute logique, le php ne devrait pas être mélangé au xhtml et la gestion des chaînes de caractères ne devrait pas faire partie du code.
Par exemple, un programme index.php à la racine ne devrait s'occuper que du code php et mettre dans des variables tout ce qui devra être affiché en fonction du traitement des langues, du contexte, de l'authentification, ... bref tout ce que php peut avoir à gérer.
Une fois les variables remplies, il y a une fusion avec un index.tpl qui ne contient que la partie xhtml (et inclusion du fichier css pour le style et des fichiers javascript pour le comportement) avec des emplacements prévus pour les variables remplies par index.php. Une fois fusionné le fichier xhtml résultant est envoyé au browser.
J'espère que ces remarques ne seront pas mal interprétées. On trouve dans tous les forums des personnes qui arrivent une fois que le travail est fini pour dire qu'il aurait été possible de faire autrement mais qui ne font jamais rien par eux mêmes.
Je fais de la recherche en développement web et pour autant n'ai jamais eu le courrage de me lancer dans le codage complet d'un CMS. C'est parce qu'à la lecture du forum j'ai eu le sentiment que, contrairement à beaucoup de communautés, vous sembliez être très ouverts et pas caractériels que je me suis permis d'intervenir.
YACS me semble suffisament intéressant et bien codé pour vous apporter des informations qui pourrait le faire encore plus progresser.
10- Gmcms
on May 23 2006 -
- le support des alphabets du monde entier. UTF-8 résoud ça et YACS le supporte.
- gérer des contenus dans plusieurs langues. Là, il y a de nombreux débats et certains CMS ont essayé d'apporter des solutions. OSCOMMERCE propose un champ de saisie pour chaque contenu par langue paramétée (exemple : j'ai configuré en et fr, alors quand je vais créer la page "règles de vente", j'aurais deux textarea, un avec le drapeau français et l'autre avec le drapeau anglais). NPDS propose d'utiliser un mot clé pour que dans un même textarea on puisse saisir du texte dans plusieurs langues sans pour autant avoir une erreur en cas de texte non traduit etc..... YACS permet de contourner ce problème par le jeu des sections et catégories. C'est une méthode comme une autre et c'est laissé à l'appréciation du webmaster.
- gérer les messages fournis par le CMS et non considérés comme du contenu. C'est dans ce cas que l'interface doit pouvoir basculer en un click dans la langue détectée ou demandée par le visiteur. Là aussi des CMS ont essayés différentes méthodes. La plupart utilisent le fichier langue à base de variables. C'est la méthode la plus connue. Cependant, elle n'est pas parfaite, car la gestion des mises à jour peut vite devenir lourde pour tout le monde quand le fichier devient énorme. Il manque des automatismes pour savoir si une chaîne existe déja et pour connaître les chaînes non traduites d'une version à l'autre (à moins de mettre les nouvelles à la fin du fichier mais alors ce n'est pas classé en suivant une logique alphabétique ou d'appartenance à un programme). D'autres CMS ont mis au point un système de type gettext mais indépendant de la librairie php avec les variables embarquées en base de données. C'est le cas de DRUPAL. Ce système est bien mais je lui reproche de devoir être sur le CMS pour effectuer la traduction.
La méthode que j'avais évoqué est donnée pour être parmis les plus rapides d'après les benchmarks effectués et pour offrir des automatismes pour les traducteurs grâce à des outils gratuits tel poedit (traduction offline avec interface graphique et possibilité de connaître les nouvelles chaînes à traduire, sans risque d'erreur en cas de fichier partiellement traduit puisque qu'une langue par défaut s'affiche toujours).
Un exemple :
Soit le fichier locale/fr_FR/LC_MESSAGES/messages.po contenant :
msgid "Hello World!"
msgstr "Bonjour le monde !"
msgid "PHP Localization Benchmark"
msgstr "Benchmark de traduction PHP"
msgid "This is just a sample page to compare the various localization methods."
msgstr "C'est just une page d'exemple pour comparer les différentes méthodes de localisation."
Après avoir détécté la langue du browser et/ou du cookie (le visiteur peut être un Français en voyage en Inde
), la variable $locale aura par exemple la valeur suivante :$locale = "fr_FR";
L'entête du programme php contiendra l'initialisation propre à gettext :
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "./locale");
textdomain("messages");A l'intérieur de la partie html, on trouvera :
_("Hello World!")
_("PHP Localization Benchmark")
_("This is just a sample page to compare the various localization methods.")Aussi simple que ça et peu de modifications à apporter aux programmes de YACS. Ca peut même être fait progressivement.
11- Cloubech
on May 23 2006 -
Au lieu d'utiliser plusieurs base de données on peut utiliser plusieurs tables préfixées par le code langue.
voilà quelques idées...
12- Gmcms
on May 23 2006 -
Travailler sur une maquette XAMPP rendrait compliqué la consolidation de base de données.
Ce choix ne peut pas se passer du couplage avec un système gettext, tel que l'a fait DRUPAL. Exportation et Importation des chaînes de caractères de la base de données pour travailler offline et re-intégrer ensuite avec un système de gestion des différences.
13- Vinc
on May 27 2006 -
14- Bernard
on May 27 2006 -
15- Tof
on June 3 2006 -
J'allais poser une question sur le multi-langue mais je vois que le sujet est déjà chaud, tant mieux !
Je vais développer bientôt un site marchand. Je pense toujours le baser sur Oscommerce, car justement le point d'achoppement principal qui m'empêche d'utiliser Yacs est la gestion du multi-langue (les autres problèmes, gestion de caddie, etc pourraient être résolus par ma pomme et intégrer à Yacs, mais je ne pense pas en avoir le temps pour ce site).
Le problèmes est tout bête, le site s'adresse à l'international, donc gestion anglais, espagnol, allemend, et peut-être chinois bientôt...
Or effectivement, le codage en dur fait dans yacs ne gère que le français et l'anglais, et aucune interface ne propose la traduction en ligne.
Personnellement, le modèle oscommerce me paraît très adapté d'un point de vue administration.
D'un point de vue programmation, je ne sais pas ce qu'il y a derrière pour l'instant, mais j'ai par contre eu l'occasion de rentrer dans d'autres outils open-source multi-langues qui sont pas mal fait de ce côté là.
egroupware est un bon exemple, à part l'outil de traduction qui est un peu complexe. dolibarr est pas mal non plus...
je parle du codage pour le programmeur, pas de la sauce qu'il y a derrière.
En tout cas, ce sujet m'intéresse...
Tof
16- Bernard
on June 3 2006 -
17- Gmcms
on June 7 2006 -
Bonjour, voici un lien avec 3 scripts que vous pouvez adapter à votre besoin de test sur YACS :
18- Gmcms
on June 7 2006 -
Pour ce qui est de oscommerce, le principe est bon mais il ne vaut mieux pas regarder derrière le rideau. Il est parfois préférable d'aller voir du côté des forks, mais sachant qu'il peut y avoir des problèmes de traduction en français. Les difficultés sont dûes à une mauvaise conception de base.
Un français s'est attaqué aux différents problèmes de oscommerce et cherche à les régler. Il fait du très bon travail mais souffre tout seul. Allez faire un tour du côté de OSCSS vous m'en direz des nouvelles.
19- Tof
on June 7 2006 -
Merci beaucoup pour ce lien, je vais étudier ça de plus près. Jusqu'à présent, j'avais plutôt regardé du côté de la Creload http://www.creloaded-fr.net/ que je trouve complète mais dure d'accès.
Tof
20- Fernand
on June 7 2006 -
Rate this page
Posted by Gmcms on May 20 2006, edited by Fernand on May 20 2006, (popular)
1- Gmcms
on May 21 2006 -