[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: gettext



David CABATON a écrit :

Bonjour la liste !

Je voudrais creer un programme multilingue (C C++).... apres recherche sur google, je m'apercois que gettext est fait pour moi, du moins c'est ce que je pense !

Mais comment utiliser gettext, je trouve pas un exemple simple du style "hello world" convertie en francais ou espagnol !

Apparement i lfaut creer un fichier po puis parametrer des variables !

Merci de votre aide !

David

Ok je viens de trouver un exemple mais qui marche pas chez moi......

Voici le source du prog :
#include <stdio.h>
#include <libintl.h>

int main() {
   textdomain("essai.po");
   printf( gettext("Hello, world !\n") );
   return 0;
}

la compil : gcc -Wall -o essai essai.c

----------------------------------------------------------------------------------------------------------
je genere le fichier po avec : xgettext -a -d hello-world -k_ -s hello.c

voici le contenu du fichier po mis a jour :

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2003-06-06 20:18+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: essai.c:11
msgid "Hello, world !\n"
msgstr "Bonjour, monde !\n"

#: essai.c:8
msgid "hello-world"
msgstr "bonjour-monde"
----------------------------------------------------------------------------------------------------------

et voici les variables du fichier /etc/profile
LANG=fr_FR
LC_NUMERIC=C
export LANG
export LC_NUMERIC

merci de m'aider, le prog affiche toujours hello world au lieu de bonjour monde....

snif :(

Voici comment j'ai fais pour mon site web (désolé il est pas encore en ligne je peut pas te prouver que cela marche mais croit moi je suis pas myto.)

Dans le répertoire racine du site j'ai un répertoire
<root>
  +    locales
   |   +    en
   |    |  +    LC_MESSAGES
   |    |   |  -    <mon_fichier>.po         #Ici les messages en anglais.
| | \ - <mon_fichier>.mo #Le nom <mon_fichier> deviendra le "nom de domaine" | + de #de la fonction textdomain() pas de fantaisie, il doit être | | #le même pour tous les fichiers .mo.
   |    |  +    LC_MESSAGES
   |    |   |  -    <mon_fichier>.po        #Ici les messages en français.
   |    |   \  -    <mon_fichier>.mo
   |   +    fr
   |       +    LC_MESSAGES
   |        |  -    <mon_fichier>.po       #Ici les messages en allemand.
   |         \  -    <mon_fichier>.mo
\ locale.alias # lien -> /etc/locale.alias

Chaque fichier po est une copie de celui obtenu par xgettext. Dans chaque copie tu traduit les messages dans la langue qui convient (suivant le répertoire dans lequel il se trouve.

Ensuite du "compile" chaque .po en .mo.

Passons au code :

Comme un script php n'est persistant en mémoire il faut pouvoir l'appeller dans chaque scripts mais reprendre le corps de la fonction te donnera une bonne idée de ce qu'il y a à faire.

function do_i18n($_domaine){
// I18N support information here
 $language = $_COOKIE['lang'];
 if(empty($language)){
$language = getPreferedLanguage(); //Récupère les infos sur la langue envoyées par le navigateur.
 }
 $lang_terr = getLanguageTerritories($language);    //
 $lang_name = getLanguageName($language);          //cf plus
 $charset   = getLanguageCharset($language);          //Récupère le chare

 /*Ici le code  que tu peut reproduire quasi directement en C*/
 putenv("LANG=" . $lang_name);

 $test = setlocale(LC_ALL, $lang_name); /* $lang_name  */
 if( FALSE==$test ){


   putenv("LANG=" . $language ."_" . $lang_terr[0] . "." . $charset);
$test = setLocale(LC_ALL, $language ."_" . $lang_terr[0] . "." . $charset);
   if(FALSE==$test){
putenv("LANG=" . $language ."_" . $lang_terr[0]); //La c'est idem qu'en C. $test = setlocale(LC_ALL,$language ."_" . $lang_terr[0]); //La c'est idem qu'en C.
     if(FALSE==$test)
       die("Ga Booo $language [$lang_name] is shit ! Test was $test !?!");
   }
 }

 textdomain($_domaine);
 bindtextdomain($_domaine, $_SERVER["DOCUMENT_ROOT"] . "locale");
}



function getLanguageName($_lang){
 switch( $_lang ){
 case "fr":
   return "french";
 case "de":
   return "deutsch";
 case "en":
   return "english";
 case "it":
   return "italian";
 default:
   return "english";
 }
}


A l'arrach ça te donnerai en C et sans variables (pour la langue allemande):

/**DU CODE AVANT**/
putenv("LANG=deutsch"); //Le putenv n'est nécessaire que si la langue à utiliser //dans le programme n'est pas celle de l'utilisateur. if( !setlocale(LC_ALL, "de_DE.ISO-8859-1") ) //setlocale renvoie NULL en cas d'échec.
    {
textdomain(<mon_fichier>); //Remplace <mon_fichier> par le nom de ton fichier mo bindtextdomain(<mon_fichier>, "<root>/locale"); //Remplace root par le chemin complet vers ton repertoire projet.
   }else{
exit(EXIT_FAILURE); //ou n'importe quoi d'autre, à toi de voire.
   }

/**DU CODE APRES**/

Autre version qui récupère le langage de l'utilisateur pour qu'il obtiennent des messages dans sa langue (plus utile mais pratique pour faire des test ;-)) :

/**DU CODE AVANT**/

if( !setlocale(LC_ALL, getenv("LANG")) ) //setlocale renvoie NULL en cas d'échec.
    {
textdomain(<mon_fichier>); //Remplace <mon_fichier> par le nom de ton fichier mo bindtextdomain(<mon_fichier>, "<root>/locale"); //Remplace root par le chemin complet vers ton repertoire projet.
   }else{
exit(EXIT_FAILURE); //ou n'importe quoi d'autre, à toi de voire.
   }

/**DU CODE APRES**/

Donc tes erreurs étaient :
   mauvais appel à textdomain() (ne pas mettre le .po)
absence du bindtextdomain() sans lequel gettext ne sais pas ou chercher le .mo. Si tu ne "bind" pas ton domaine linguistique gettext cherche ton fichier .mo dans /usr/share/locale .

Voilà j'espère que cela t'aide plus .

Nicolas




Reply to: