IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Gettext

De SergiTurWiki
Share/Save/Bookmark
Dreceres ràpides: navegació, cerca
http://es.wikipedia.org/wiki/Gettext

Contingut

Paquet Debian

Segurament ja el teniu instal·lat:

$ sudo apt-get install gettext
[sudo] password for sergi: 
S'està llegint la llista de paquets... Fet
S'està construint l'arbre de dependències       
S'està llegint la informació de l'estat... Fet
gettext ja es troba en la versió més recent.
S'ha marcat gettext com instal·lat manualment.
0 actualitzats, 0 nous a instal·lar, 0 a suprimir i 0 no actualitzats.

Extensió php, paquet Debian

$ sudo apt-get install php-gettext

Cal tornar a iniciar Apache? Doncs sí (problema de portabilitat o quan no es té accés al servidor apache):

$ sudo /etc/init.d/apache2 reload

Recursos:

gettextutils

Instal·lació:

$ sudo apt-get install gettext

Les ordres són:

$ dpkg -L gettext | grep bin
...
/usr/bin/msgcmp
/usr/bin/msgfmt
/usr/bin/msgmerge
/usr/bin/msgunfmt
/usr/bin/xgettext
/usr/bin/msgattrib
/usr/bin/msgcat
/usr/bin/msgcomm
/usr/bin/msgconv
/usr/bin/msgen
/usr/bin/msgexec
/usr/bin/msgfilter
/usr/bin/msggrep
/usr/bin/msginit
/usr/bin/msguniq
/usr/bin/recode-sr-latin
/usr/bin/gettextize
/usr/bin/autopoint
/usr/lib/preloadable_libintl.so

Com funciona?

gettext suposa que tenim un codi similar a:

<?php
 // I18N support information here
 $language = 'en';
 putenv("LANG=$language"); 
 setlocale(LC_ALL, $language);
 
 // Set the text domain as 'messages'
 $domain = 'messages';
 bindtextdomain($domain, "/www/htdocs/site.com/locale"); 
 textdomain($domain);
 
 echo gettext("A string to be translated would go here");
 ?>

Amb les eines de gettext, podrem traduir tots els textos indicats amb gettext.

NOTA: Per tant tingueu en compte que encara que no tingueu pensat traduir l'aplicació a curt termini podeu utilitzar gettext, i així el codi font ja està preparat.

xgettext. Creant una plantilla extraient tots els strings gettext

xgettext -ktranslate -kngettext:1,2 file.php

o

xgettext -n *.php

o

xgettext -a -n --from-code=utf-8 *.php, o amb intltool-update

també hi ha la eina

Exemple amb c:

$ xgettext -d hello -s -o hello.pot hello.c

Es continuaria amb msginit:

$ msginit -l or_IN -o oriya.po -i hello.pot
IMPORTANT: xgettext només extrau els textos que es mostre mitjançant la funció gettext o la macro o alias equivalent (normalment _())

msginit. Crear un nou fitxer .po a partir d'una plantilla (pot)

Si no teniu cap fitxer POT (po template), us donarà el següent error:

$ msginit
msginit: No s’ha trobat cap fitxer «.pot» al directori actual.  Per favor,
         especifiqueu el fitxer POT d’entrada amb l’opció «--input».
Proveu «msginit --help» per a obtenir més informació.

msgfmt. Crear una catàleg de missatges (compilar)

Un cop tenim les traduccions es recomanable crear un catàleg, que no és res més que un fitxer binari (compilació del fitxer .po). El fet de convertir a binari provoca que l'execució de les utilitats gettext sigui més ràpida.

$msgfmt -c -v -o hello.mo oriya.po

El fitxer resultant és un fitxer mo

$ mkdir -p /usr/share/locale/or_IN/LC_MESSAGES
$ cp hello.mo /usr/share/locale/or_IN/LC_MESSAGES

msgcat. Concatenar fitxers po

TODO

msgconv. Converteix un catàleg d'una codificació de caràcters a un altre

TODO

msggrep. Buscar missatges en un cataleg

TODO

msmerge. Merging les traduccions noves i les antigues

$ xgettext -d hello -s -o hello-new.pot hello.c
$ msgmerge -s -U oriya.po hello-new.pot

Macros, alias, etc..

En C:

#define _(STRING)    gettext(STRING)

A PHP hi ha definit un alias automàticament. Per tant:

// Print a test message
echo gettext("Welcome to My PHP Application");

i

// Or use the alias _() for gettext()
echo _("Have a nice day");

Són equivalents.


Recursos:

Glossari de termes

  • domain name: és el nom dels fitxers .pot, .po i .mo. Típicament messages.po
  • .pot: portable object template
  • .po: portable object
  • .mo:

Editors

PHP

Vegeu també PHP

Hi ha dos possibilitats:

Extensió PHP

Comprovar si el nostre php té suport per a getext

Es pot fet consultant phpinfo. Creeu un fitxer phpinfo.php

<?phpinfo();?>

Ha de sortir una secció anomenada gettext amb:

GetText Support 	enabled

Inicialització amb l'extensió de PHP

Exemple:

Fitxer localization.php:

 <?php
 $locale = "de_DE";
 if (isSet($_GET["locale"])) $locale = $_GET["locale"];
 putenv("LC_ALL=$locale");
 setlocale(LC_ALL, $locale);
 bindtextdomain("messages", "./locale");
 textdomain("messages");
 ?>

Per utilitzar-lo:

 require_once("localization.php")

Llibreria (php-gettext)

Exemple complet

Es fa un include al fitxer on volem posar text internacionalitzat.

//Localització i internacionalització
require_once _INCLUDES.'localization.php';

On el fitxer localization.php:

// define constants
define("_PROJECT_DIR", realpath('./'));
define("_LOCALE_DIR", _PROJECT_DIR .'/locales');
define("_DEFAULT_LOCALE", 'ca_ES.UTF8'); 

require_once(_PHP_GETTEXT_LIB.'gettext.inc');

//Nom utilitzat per l'exemple localization_example.php
$supported_locales = array('en_US', 'sr_CS', 'de_CH','es_ES');
$encoding = 'ISO-8859-1';

//Agafar el locale del paràmetre lang
$locale = (isset($_GET['lang']))? $_GET['lang'] : _DEFAULT_LOCALE;
//DEFAULT_LOCALE = ca_ES.UTF8 

// gettext setup
T_setlocale(LC_MESSAGES, $locale);
// Set the text domain as 'messages'
$domain = 'messages';
T_bindtextdomain($domain, _LOCALE_DIR);
T_bind_textdomain_codeset($domain, $encoding);
T_textdomain($domain); 

// gettext setup
#setlocale(LC_MESSAGES, $locale);
// Set the text domain as 'messages'
#$domain = 'messages';
#bindtextdomain($domain, _LOCALE_DIR);
#bind_textdomain_codeset($domain, $encoding);
#textdomain($domain);

header("Content-type: text/html; charset=$encoding");
?>

TroubleShooting. Resolució de problemes

No funciona gettext es_ES quan estem amb un sistema amb ca_ES

Normalment és degut a que al tenir el sistema instal·lat en català, no tenim els locales espanyols.... Cal instal·lar el locale:

$ sudo locale-gen es_ES.UTF-8
NOTA: Heu d'indicar el locale complet o el que utilitzi l'aplicació que us interessa! Ha de ser completament igual, per exemple no és el mateix es_ES que es_ES.UTF-8

I reiniciar Apache si és una aplicació web o LAMP:

$ sudo /etc/init.d/apache2 restart

Per exemple, a mi m'ha passat amb l'aplicació LAMP Gosa.

No s'actualitzen les localitzacions amb php extension

Cal reiniciar el servidor web!

$ sudo /etc/init.d/apache2 restart
IMPORTANT: Fixeu-vos que això fa poc útil la extensió ja uqe la majoria de desenvolupadors no són administradors del servidor web

TODO: Hi ha algun altre solució? Utilitzar la llibreria en comptes de la extensió!

Problemes de la php_extension

Es poc portable perquè depèn del suport per a locales del servidors i de la configuració de php.

Per instal·lar locales:

$ sudo locale-gen en_US

Recursos:

Vegeu també

Enllaços externs

OpenFPnet
IES Nicolau Copèrnic