r5 - 07 Nov 2007 - JoenioCosta
Fazendo um HelloWorld falar vários idiomas
Problema
Como fazer um sistema com suporte a L10N? Você precisa que seu sistema tenha suporte a vários idiomas e que novos idiomas sejam adicionados a qualquer momento?Solução
Utilize o módulo Locale::Maketext em conjunto com Locale::Maketext::Lexicon.Discussão
Abaixo segue um simples helloworld modo texto a ser executado via linha de comando... O exemplo foi desenvolvido e testado em ambiente Gnu/Linux utilizando Perl v5.8.8, mas você deve consiguir executá-lo em qualquer computador que tenha Perl instalado.HelloWorld::L10N
Primeiro devemos criar um módulo que use como base o Locale::Maketext.
package HelloWorld::L10N;
use base 'Locale::Maketext';
use Locale::Maketext::Lexicon {
'en' => ['Auto'],
'*' => ['Gettext' => 'po/*/hello.po'],
_auto => 1,
};
my $lh = __PACKAGE__->get_handle();
sub _ { $lh->maketext(@_) }
1;
Neste módulo definimos que:
- O idioma padrão será o ingles (
'en' => ['Auto']) - A frase original (não traduzida) será utilizada caso a tradução ainda não tenha sido feita (
_auto => 1) - E que a localização para os arquivos de tradução se encontrarão na seguinte estrutura de diretórios:
- po
-
pt_br
-

hello.po
-
en_us
-

hello.po
-
zh_tw
-

hello.po
-
fr
-

hello.po
LANGUAGE, o Locale::Maketext irá detectar automagicamente o idioma a ser utilizado através da chamada __PACKAGE__->get_handle().
A função _ definida na ultima linha deste módulo irá criar as mensagens "localizadas", ou seja, mensagens traduzidas para o idioma corrente detectado no ambiente onde o sistema será executado. Esta função poderia ter qualquer outro nome, mas utilizar um simples caracter _ evita poluição no código, pois teoricamente esta função deverá ser chamada em quase todos os locais do sistema.
HelloWorld
Agora vamos criar o módulo HelloWorld que possui a funcionalidade do nosso sistema em sí.
package HelloWorld;
use HelloWorld::l10n;
use Exporter 'import';
@EXPORT = qw( hello found );
sub hello {
return _('Hello world!'), "\n";
}
sub found {
return _("Found [*,_1,file,files].", $_[0]), "\n";
}
1;
Este módulo faz utilização do módulo acima e define os métodos hello e found, onde apenas retornam as mensagens 'Hello world!' e "Found [*,_1,file,files]." já localizados respectivamente. O método found foi utilizado apenas para exemplificar a possibilidade de tratamento diferenciado para mensagens no singular e plural pelo Locale::Maketext.
helloworld.pl executando...
Abaixo o script que utiliza o módulo HelloWorld:#!/usr/bin/perl use strict; use HelloWorld; print hello(); print found(1); print found(3);Defina seu ambiente como Portugues do Brasil alterando a variável de ambiente
LANGUAGE para pt_BR e execute o script:
$ perl helloworld.pl $ Hello world! $ Found 1 file. $ Found 3 files.Não aconteceu nada, correto? Claro! Porque nós ainda nao geramos os arquivos com as traduções...
makepot.pl traduzindo...
OLocale::Maketext::Lexicon traz em seu conjundo de módulos o módulo Locale::Maketext::Extract que é uma mão na roda para executar a tarefa de varrer todos os fontes do seu sistema em busca de mensagens que devem ser traduzidas.
#!/usr/bin/perl
use strict;
use warnings;
use Locale::Maketext::Extract;
my $Ext = Locale::Maketext::Extract->new();
mkdir './po' unless -e './po';
$Ext->read_po('po/hello.pot') if -e 'po/hello.pot';
$Ext->extract_file($_) for (<*.pl>, <*.pm>);
$Ext->compile(1);
$Ext->write_po('po/hello.pot');
O script acima faz uso desse módulo para percorrer todos os arquivos com extensão .pl e .pm em busca de mensagens a ser traduzidas e as salva em po/hello.pot. Este arquivo .pot é um template a ser utilizado para iniciar a tradução dos diversos idiomas que voce pretente suportar em seu sistema e não deve ser editado manualmente.
hello.pot
# 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: YEAR-MO-DA HO:MI+ZONE\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" #: HelloWorld.pm:11 #. ($_[0]) msgid "Found [*,_1,file,files]." msgstr "" #: HelloWorld.pm:8 msgid "Hello world!" msgstr ""A execução do script deverá gerar o arquivo
hello.pot semelhante ao arquivo acima no diretório po, para iniciar a tradução para o português do Brasil crie a pasta pt_BR dentro de po, copie o arquivo hello.pot para lá e altere a extensão dele para .po.
Cada entrada no arquivo acima possui um comenário (#: HelloWorld.pm:8) indicando onde a mensagem está seguido da mensagem original (msgid "Hello world!") e finalmente a mensagem traduzida (msgstr ""). Aqui a mensagem não deve ser traduzida, a tradução deve ser feita somente no arquivo correspondente ao idioma localizado na estrutura de diretórios dentro de po.
pt_BR/hello.po
Agora é só traduzir as mensagens como no exemplo abaixo...# 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: YEAR-MO-DA HO:MI+ZONE\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" #: HelloWorld.pm:11 #. ($_[0]) msgid "Found [*,_1,file,files]." msgstr "Encontrado [*,_1,arquivo,arquivoss]." #: HelloWorld.pm:8 msgid "Hello world!" msgstr "Alô mundo!"ps.: Note que a mensagem
"Found [*,_1,file,files]." traz a palavra file no singular e no plural, isto é útil para que seja possível adaptar a tradução corretamente para idiomas que possuem tratamento diferenciado para essas duas formas.
... e executar o script helloworld.pl para ver o resultado final:
$ perl helloworld.pl $ Alô mundo! $ Encontrado 1 arquivo. $ Encontrado 3 arquivos.
Referências
- http://search.cpan.org/src/AUTRIJUS/Locale-Maketext-Lexicon-0.62/docs/webl10n.html
- http://pt.wikipedia.org/wiki/I18n
- http://www.gnu.org/software/gettext/manual/gettext.html
