Localització (suport multiidioma)

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció. Exemple inicial

Per a Ubuntu, està molt ben explicat a:

http://www.sourcerally.net/regin/49-How-to-get-PHP-and-gettext-working-(ubuntu,-debian)

Gettext és una llibreria que permet implementar una nova versió d'idioma en un projecte PHP de forma fàcil (no és necessari barallar-se amb centenars o milers de definicions). Bàsicament, cada vegada que tens una cadena de text que s'ha de traduir, en el codi PHP posaràs:

<?php
    echo _('Text to be translated');
?>

1. Instal.lació del paquet gettext

$ sudo apt-get install php-gettext

2. Instal.lar els locals

Per locals entenem els idiomes que s'han de traduir. Per fer una bona traducció necessites utilitzar funcions com ara strftime() per tal de visualitzar les dates en el idioma. gettext també el necessita.

Per instal.lar els locals espanyol, anglès i català:

$ sudo locale-gen ca_ES
$ sudo locale-gen es_ES
$ sudo locale-gen en_GB

A Ubuntu es poden veure tots els locals instal.lats a la màquina a /usr/share/i18n/SUPPORTED

3. Una aplicació PHP senzilla

fitxer helloworld.php

<?php
    bindtextdomain('messages', './locales/');
    textdomain('messages');
    switch ($_GET['l']) {
        case 'ca':
        setlocale(LC_ALL,'ca_ES');
        break;
        case 'es':
        setlocale(LC_ALL,'es_ES');
        break;
        case 'en':
        default:
        setlocale(LC_ALL,'en_GB');
        break;
    }
    echo _('Hello World');
?>

locales és el directori on agruparem totes les traduccions

La comanda _ és un àlies de la funció gettext(). Podríem haver escrit:

echo gettext('Hello World');

4. Extreure les cadenes i fer la traducció

Ara hem de començar a traduir l'aplicació a partir de les cadenes que hem marcat per a ser traduides.

$ xgettext helloworld.php

o millor: (protesta si hi ha accents)

$ xgettext --from-code=UTF-8 configuration.php

Es genera un fitxer anomenat message.po.

Ara hem de crear els directoris on gettext anirà a mirar els fitxers de traduccions.

$ mkdir -p locales/ca/LC_MESSAGES
$ mkdir -p locales/en/LC_MESSAGES
$ mkdir -p locales/es/LC_MESSAGES

i movem el fitxer de traduccions al destí correcte

$ mv messages.po locales/en/LC_MESSAGES
$ cp locales/en/LC_MESSAGES/messages.po locales/es/LC_MESSAGES/messages.po
$ cp locales/en/LC_MESSAGES/messages.po locales/ca/LC_MESSAGES/messages.po

Ara editem els fitxers a traduir:

$ joe locales/es/LC_MESSAGES/messages.po

# 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"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-10-26 13:40+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"


#: example.php:15
msgid "Hello World"
msgstr ""

Hem de fer dues coses. Primer, dir el charset que utilitzarem:

"Content-Type: text/plain; charset=CHARSET\n"

canviar-ho per

"Content-Type: text/plain; charset=UTF-8\n"

i fer la traducció pròpiament dita

msgid "Hello World"
msgstr ""

canviar-ho per:

msgid "Hello World"
msgstr "Hola mundo!"

i el mateix per al fitxer català

Ara finalment hem de compilar les traduccions:

$ msgfmt locales/es/LC_MESSAGES/messages.po -o locales/es/LC_MESSAGES/messages.mo
$ msgfmt locales/ca/LC_MESSAGES/messages.po -o locales/ca/LC_MESSAGES/messages.mo

I ja està, podem veure com canvia el missatge en els diferents idiomes:

Altra informació:

Millores. Automatització

http://www.codelog.net/tips/playing-with-xgettext

En la introducció anterior s'ha posat de manifest el funcionament de gettext, però calen unes millores. La primera és que volem fer un sol fitxer per a tots els fitxers php que hi puguin haver en l'aplicació. La segona és que, evidentment, hem de conservar les parts que ja estan traduides.

$ mv locales/es/LC_MESSAGES/messages.po messages.po
$ find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
$ mv messages.po locales/es/LC_MESSAGES/messages.po

Explicació: movem el fitxer castellà al directori principal de l'aplicació. Busquem tots els fitxers php, i aplicant-los gettext amb les opcions adequades, aconseguim fer un merge conservant les parts que ja estan traduïdes. Tornem a copiar el fitxer messages.po al seu directori.

No cal dir que aquest procés es pot automatitzar fàcilment amb un script executable, que faci el procés per a tots els idiomes a traduir.

traductor.sh:

#castellà
mv locales/es/LC_MESSAGES/messages.po messages.po
find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
mv messages.po locales/es/LC_MESSAGES/messages.po

#català
mv locales/ca/LC_MESSAGES/messages.po messages.po
find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -
mv messages.po locales/ca/LC_MESSAGES/messages.po
$ sudo chmod a+x traductor.sh

Millores. Automatització II

Basant-me en el punt anterior, aquí hi ha els apunts per a un cas real (arthropoda.joanillo.org): (fitxer localitzacio.txt del projecte)

Resum de comandes per fer la localització
===========================================
Primer comencem pel cas senzill de canviar un fitxer
xgettext --from-code=UTF-8 configuration.php

cp messages.po locales/ca/LC_MESSAGES/messages.po
cp messages.po locales/es/LC_MESSAGES/messages.po
cp messages.po locales/en/LC_MESSAGES/messages.po

joe locales/ca/LC_MESSAGES/messages.po
joe locales/es/LC_MESSAGES/messages.po
joe locales/en/LC_MESSAGES/messages.po

msgfmt locales/ca/LC_MESSAGES/messages.po -o locales/ca/LC_MESSAGES/messages.mo
msgfmt locales/es/LC_MESSAGES/messages.po -o locales/es/LC_MESSAGES/messages.mo
msgfmt locales/en/LC_MESSAGES/messages.po -o locales/en/LC_MESSAGES/messages.mo

Ja funciona. Continuem fent modificacions que s'han de tornar a traduir: (de moment només modifico el fitxer configuration.php)

cp locales/ca/LC_MESSAGES/messages.po messages.po
xgettext --from-code=UTF-8 -j configuration.php
cp messages.po locales/ca/LC_MESSAGES/messages.po
joe locales/ca/LC_MESSAGES/messages.po

cp locales/es/LC_MESSAGES/messages.po messages.po
xgettext --from-code=UTF-8 -j configuration.php
cp messages.po locales/es/LC_MESSAGES/messages.po
joe locales/es/LC_MESSAGES/messages.po

cp locales/en/LC_MESSAGES/messages.po messages.po
xgettext --from-code=UTF-8 -j configuration.php
cp messages.po locales/en/LC_MESSAGES/messages.po
joe locales/en/LC_MESSAGES/messages.po

Ara si vull veure els resultats he de compilar (veure més avall)

Ara vaig a mirar ja tots els fitxers modificats en la carpeta. (Aquí comença el codi real)

cp locales/ca/LC_MESSAGES/messages.po messages.po
find . -type f -iname "*.php" | xgettext --from-code=UTF-8 -j -f -
cp messages.po locales/ca/LC_MESSAGES/messages.po
joe locales/ca/LC_MESSAGES/messages.po

cp locales/es/LC_MESSAGES/messages.po messages.po
find . -type f -iname "*.php" | xgettext --from-code=UTF-8 -j -f -
cp messages.po locales/es/LC_MESSAGES/messages.po
joe locales/es/LC_MESSAGES/messages.po

cp locales/en/LC_MESSAGES/messages.po messages.po
find . -type f -iname "*.php" | xgettext --from-code=UTF-8 -j -f -
cp messages.po locales/en/LC_MESSAGES/messages.po
joe locales/en/LC_MESSAGES/messages.po

I ara compilem:
msgfmt locales/es/LC_MESSAGES/messages.po -o locales/es/LC_MESSAGES/messages.mo
msgfmt locales/ca/LC_MESSAGES/messages.po -o locales/ca/LC_MESSAGES/messages.mo
msgfmt locales/en/LC_MESSAGES/messages.po -o locales/en/LC_MESSAGES/messages.mo

Eines. poEdit

poEdit és una eina gràfica per mantenir les traduccions d'un projecte.

A Ubuntu:

$ sudo apt-get install poedit

Està disponible a Aplicacions > Programació > poEdit

Traduir un fitxer *.po

Amb el script vist anteriorment, ./traductor.sh, actualitzo els meus catàlegs. Ara ja tinc els fitxers messages.po de les traduccions catalna i anglesa en les últimes versions. poEdit m'ajuda a fer la traducció amb un entorn gràfic, i compila automàticament creant els respectius fitxers messages.mo.

Fitxer > obrir catàleg, i escullo el meu fitxer *.po

Poso el meu nom i mail, i en la pestanya Analitzadors escullo PHP. Tot lo altre ho deixo igual.

Crear un nou catàleg (de moment, no)

La idea és que quan modifiqui els meus fitxers font (*.php) amb noves frases per traduir, s'actualitzin els catàlegs. És a dir, dins l'entorn de poEdit fer la feina que fa el script traductor.sh

Configuració de l'analitzador: és important perquè recorrerem tots els fitxers PHP a la cerca de les cadenes a traduir

aquí veig com s'invoca a xgettext i que d'alguna manera s'assembla a com s'invoca en el fitxer traductor.sh:

find . -type f -iname "*.php" | xgettext --keyword=__ --keyword=_e -j -f -

Per fer la traducció a l'anglès des de zero hem de crear un nou catàleg: (aquesta part no m'ha sortit...)

Fitxer > nou catàleg

Fico les dades del traductor, idioma i país (en_US)

Ruta base: /home/joan/web_empresalibre

i anomeno el fitxer com a messages.po en la ruta adequada: ~/web_empresalibre/locales/en/LC_MESSAGES/

Per defecte, veig que poEdit utilitza aspell (interactive spell checker) per revisar els fonts originals a la cerca de les sentències a traduir

Gettext a Windows

http://www.aota.net/forums/showthread.php?threadid=10615

Aquest exemple s'ha fet amb el EasyPHP.

fitxer index.php:

<?php
    echo "<h2>Exemple de localització</h2>";
    echo _('Text to be translated');
?>

falla perquè no troba la funció _().

Puc descarregar-me gettext, que és un projecte GNU, de http://gnuwin32.sourceforge.net/packages/gettext.htm. Agafo l'opció Complete package, except sources (tamany 4Mb).

Queda instal.lat a C:\Archivos de programa\GnuWin32\, i veig que entre d'altres utilitats hi ha el binari xgettext.exe (xgettext és part de gettext):

C:\Archivos de programa\GnuWin32\bin\xgettext.exe

En el fitxer php.ini del EasyPHP descomento l'opció

extension=php_gettext.dll

i reinicio el EasyPHP

Puc provar que funciona fent:

C:\> cd C:\Archivos de programa\GnuWin32\bin
...bin\> xgettext --default-domain=C:\Archiv~1\GnuWin32\bin\traduir -k_ C:\Archiv~1\EasyPHP1-8\www\localitzacio\index.php

i en el directori del xgettext es genera el fitxer traduir.po, que té per contingut:

# 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"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-04-24 13:30-0300\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"

#: C:\Archiv~1\EasyPHP1-8\www\localitzacio\index.php:3
msgid "Text to be translated"
msgstr ""

creem els directoris que han d'incloure les traduccions catalana i castellana:

locales/ca_ES/LC_MESSAGES/
locales/es_ES/LC_MESSAGES/

Generem el fitxer .mo:

...bin\> msgfmt -o traduir.mo traduir.po

i per veure que funciona, modifiquem el fitxer index.php:

<?php
putenv("LANG=ca_ES");
setlocale(LC_ALL,'ca_ES');
bindtextdomain("traduir", "./locales/"); 
textdomain("traduir");

echo "<h2>exemple de localitzacióbr</h2>";
echo _('Text to be translated');
?>

i veiem com efectivament es mostra la informació traduida al català


PoEdit a Windows

http://www.mclibre.org/consultar/php/lecciones/php_gettext.html

La versió de PoEdit per a Windows (poedit-1.4.2-setup.exe) es pot descarregar de: http://www.poedit.net/download.php#win32

Instal.lem l'executable. La primera vegada haurem de configurar l'aplicació. Posem el nostre nom i mail, mirem quin editor per defecte hi ha posat, i com a analitzador mirem quines opcions tenim per al llenguatge PHP:

Idioma: PHP
extensió: *.php
invocació de l'analitzador: xgettext --force-po -o %o %C %K %F

creat per Joan Quintana Compte, març 2009

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines