quinta-feira, 12 de agosto de 2010

Internacionalização de sites / aplicações web com php

Salve galera, muitas vezes é necessário fazer um site ou aplicação com suporte a multilinguagem o que fazer nestas horas? Existem boas alternativas, criar um arquivo com arrays com as traduções, ou scripts javascripts, ou outras soluções.

Diante disto encontrei a solução usando o getTEXT que de forma resumida sobrepõe textos lendo das traduções em arquivos gerados.

Para utilizar o getTEXT deve estar ativado no php, e particular mente utilize ou o chamado gettext(string) ou apenas 'echo _(string)' [o _ é um alias (apelido) para a função getTEXT]

Internacionalização (i18n – de InternacionalizatioN) de aplicações em PHP é algo
relativamente simples: Vejamos em alguns passos como criar um “hello world” e
internacionaliza-lo. Note que gettext deve estar disponível para a utilização:

1 – Criação da aplicação: Pré gettext
// arquivo hello.php
echo “hello world\n”;
?>

2 – Criação da aplicação: Preparando para uso de gettext
// arquivo hello_gt.php
$lang = ‘en’;
// definimos em uma variavel de ambiente qual o idioma padrao sendo utilizado
putenv(“LANG=$lang”);
// e definimos tambem as informacoes de localizao padrao
setlocale(LC_ALL, $lang);
// e exibimos a mensagem “hello world” no idioma especificado
// Note o “_”: Este e’ um alias para a funcao gettext. _(‘msg’) e’
// equivalente a gettext(‘msg’). Esta funcao sera a responsavel pela
// traducao de “hello world”
echo _(“hello world\n”);
?>

Em ambos os casos, a execução irá apenas exibir a mensagem “hello world”:
$ php hello.php
hello world
$ php hello_gt.php
hello world
3 – Extraindo as strings da aplicação
Para efetuarmos as traduções, é necessário criar um arquivo com as mensagens que a aplicação utiliza. Esta extração pode ser efetuada utilizando o programa “xgettext”:
$ xgettext -o hello.po hello_gt.php
Isso irá criar um arquivo chamado “hello.po”, que é o arquivo com as mensagens que a aplicação possui. Utilizando este arquivo como base, podemos criar arquivos de tradução para outros idiomas.
4 – Criando traduções para outros idiomas:
Utilizando o arquivo “hello.po” criado anteriormente como base, criaremos traduções para português do Brasil (pt_BR) e alemão (de_DE). Os passos são os seguintes:
4.1 – Criamos a seguinte estrutura de diretórios:
a: locale/pt_BR/LC_MESSAGES/
b: locale/de_DE/LC_MESSAGES/
4.2 – Copiamos o arquivo “hello.po” para o diretório “locale/pt_BR/LC_MESSAGES/” e para
“locale/de_DE/LC_MESSAGES/”
4.3 – Editamos estes arquivos recém copiados. As partes do arquivo que devem ser editadas são bastante simples de serem encontradas: Vejamos como ficará o arquivo “locale/pt_BR/LC_MESSAGES/hello.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 , YEAR.
#
#, fuzzy
msgid “”
msgstr “”
“Project-Id-Version: PACKAGE VERSION\n”
“Report-Msgid-Bugs-To: \n”
“POT-Creation-Date: 2007-02-17 16:22-0200\n”
“PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n”
“Last-Translator: FULL NAME \n”
“Language-Team: LANGUAGE \n”
“MIME-Version: 1.0\n”
“Content-Type: text/plain; charset=iso-8859-1\n”
“Content-Transfer-Encoding: 8bit\n”

#: hello_gt.php:17
msgid “hello world\n”
msgstr “Olá mundo”

Ou seja, editamos a “msgstr” referente a msgid “hello world\n” (a última linha) e o charset utilizado pelo arquivo (“Content-Type: text/plain; charset=iso-8859-1\n”) O mesmo deve ser feito para o arquivo “locale/de_DE/LC_MESSAGES/hello.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 , YEAR.
#
#, fuzzy
msgid “”
msgstr “”
“Project-Id-Version: PACKAGE VERSION\n”
“Report-Msgid-Bugs-To: \n”
“POT-Creation-Date: 2007-02-17 16:22-0200\n”
“PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n”
“Last-Translator: FULL NAME \n”
“Language-Team: LANGUAGE \n”
“MIME-Version: 1.0\n”
“Content-Type: text/plain; charset=iso-8859-1\n”
“Content-Transfer-Encoding: 8bit\n”

#: hello_gt.php:17
msgid “hello world\n”
msgstr “hallo welt\n”

4.4 – “Compilamos” o arquivo com as mensagens, para que possa ser utilizado pelo gettext. Para utilizarmos as mensagens que acabamos de traduzir, precisamos gerar um arquivo binário que o gettext irá utilizar para efetuar as traduções. Para criarmos esse arquivo binário, utilizamos o programa “msgfmt”:
$ msgfmt locale/de_DE/LC_MESSAGES/hello.po -o locale/de_DE/LC_MESSAGES/hello.mo
$ msgfmt locale/pt_BR/LC_MESSAGES/hello.po -o locale/pt_BR/LC_MESSAGES/hello.mo
Com isso serão criados dois novos arquivos: “locale/pt_BR/LC_MESSAGES/hello.mo” e “locale/de_DE/LC_MESSAGES/hello.mo”.
5 – Modificando a aplicação para utilizar os novos idiomas:
Após os 4 passos anteriores, já estamos habilitados a utilizar dois novos idiomas na aplicação.
Vejamos como utilizar em “pt_BR”
// arquivo hello_gt.php
$lang = ‘pt_BR’;
// definimos em uma variavel de ambiente qual o idioma padrao sendo utilizado
putenv(“LANG=$lang”);
// e definimos tambem as informacoes de localizao padrao
setlocale(LC_ALL, $lang);
// definimos que o domínio de textos “hello” esta localizado no diretorio “locale/”
bindtextdomain(‘hello’,‘locale/’);
// e definimos que iremos utilizar o dominio de textos “hello”
textdomain(‘hello’);
// e exibimos a mensagem “hello world” no idioma especificado
// Note o “_”: Este e’ um alias para a funcao gettext. _(‘msg’) e’
// equivalente a gettext(‘msg’). Esta funcao sera a responsavel pela
// traducao de “hello world”
echo _(“hello world\n”);
?>

Executando temos:
$ php hello_gt.php
Ola mundo
Vejamos como utilizar em “de_DE”
// arquivo hello_gt.php
$lang = ‘de_DE’;
// definimos em uma variavel de ambiente qual o idioma padrao sendo utilizado
putenv(“LANG=$lang”);
// e definimos tambem as informacoes de localizao padrao
setlocale(LC_ALL, $lang);
// definimos que o domínio de textos “hello” esta localizado no diretorio “locale/”
bindtextdomain(‘hello’,‘locale/’);
// e definimos que iremos utilizar o dominio de textos “hello”
textdomain(‘hello’);
// e exibimos a mensagem “hello world” no idioma especificado
// Note o “_”: Este e’ um alias para a funcao gettext. _(‘msg’) e’
// equivalente a gettext(‘msg’). Esta funcao sera a responsavel pela
// traducao de “hello world”
echo _(“hello world\n”);
?>

Executando temos:
$ php hello_gt.php
hallo welt
E assim vimos, simples e rapidamente, como internacionalizar uma aplicação.
É isso.


Existe uma pequena situação em que o arquivo criado quando configurado na aplicação fica em cache no servidor e sempre é necessário reiniciar o server, então utilizando a esquemática abaixo não é necessário

// settings you may want to change
$locale = "en";  // the locale you want
$locales_root = "locale";  // locales directory
$domain = "hello"; // the domain you're using, this is the .PO/.MO file name without the extension

// activate the locale setting
setlocale(LC_ALL, $locale);
setlocale(LC_TIME, $locale);
putenv("LANG=$locale");
// path to the .MO file that we should monitor
$filename = "$locales_root/$locale/LC_MESSAGES/$domain.mo";
$mtime = filemtime($filename); // check its modification time
// our new unique .MO file
$filename_new = "$locales_root/$locale/LC_MESSAGES/{$domain}_{$mtime}.mo";

if (!file_exists($filename_new)) {  // check if we have created it before
      // if not, create it now, by copying the original
      copy($filename,$filename_new);
}
// compute the new domain name
$domain_new = "{$domain}_{$mtime}";
// bind it
bindtextdomain($domain_new,$locales_root);
// then activate it
textdomain($domain_new);
// all done

0 comentários:

Postar um comentário