DEV Community

Karine Vieira for Vídeos de Ti

Posted on

Internacionalização com GetText no Rails

Quando pensamos em internacionalização (i18n) em projetos Rails, a abordagem mais comum é utilizar a API nativa do framework com chaves de tradução. No entanto, recentemente descobri uma alternativa que torna esse processo mais direto e com maior visibilidade do conteúdo traduzido: o uso do GetText.

GetText é um framework utilizado no ecossistema Linux, que oferece um conjunto de ferramentas para facilitar a tradução de textos em aplicações. Integrado ao Rails, ele permite uma forma mais automática de localizar strings, sem a necessidade de criar e gerenciar nomes de chaves.

No modelo tradicional com I18n, criamos chaves de tradução e mapeamos seus conteúdos em arquivos YML. Nas views, essas chaves são utilizadas da seguinte forma:

t(".empty_state_message")
# => Nenhum resultado encontrado
Enter fullscreen mode Exit fullscreen mode

Já com GetText, podemos escrever diretamente o texto original:

_("Nenhum resultado encontrado")
# => Nenhum resultado encontrado
Enter fullscreen mode Exit fullscreen mode

Essa abordagem destaca imediatamente o conteúdo que será traduzido, tornando o código mais legível e intuitivo.

Setup

Instalação das Gems

Para integrar o GetText ao Rails, instalei as gems gettext_i18n_rails e gettext. Apesar de gettext ser uma dependência opcional da gettext_i18n_rails, vale a pena incluí-la no projeto, pois ela oferece rake tasks bastante úteis:

  • Para adicionar suporte a um novo idioma:
LANGUAGE=xx rake gettext:add_language
Enter fullscreen mode Exit fullscreen mode

Substitua xx pelo código do idioma desejado, por exemplo, en para inglês. A lista completa dos idiomas suportados está disponível aqui.

  • Para buscar traduções ausentes e adicioná-las aos arquivos .po:
rake gettext:find
Enter fullscreen mode Exit fullscreen mode

Configurações iniciais

Depois da instalação, é necessário criar um initializer para definir os domínios de tradução e os idiomas disponíveis. Para isso, usamos classes da gem fast_gettext, já que gettext_i18n_rails atua como um wrapper para facilitar a integração do GetText com projetos Rails.

# config/initializers/gettext_i18n_rails.rb
FastGettext.add_text_domain "app", path: "locale", type: :po
FastGettext.default_available_locales = ["pt_BR", "en", "es"]
FastGettext.default_text_domain = "app"
Enter fullscreen mode Exit fullscreen mode

Essa configuração permite organizar as traduções por domínio. No exemplo acima, usei apenas o domínio app para fins de demonstração, mas é possível definir domínios separados por módulos da aplicação, evitando centralizar todas as traduções em um único arquivo.

Além disso, ajuste o before_action responsável por definir o idioma da aplicação para também atualizar o locale do GetText:

 def set_locale
   locale = params[:locale] || I18n.default_locale

+  FastGettext.set_locale(locale)
   I18n.locale = locale
 end
Enter fullscreen mode Exit fullscreen mode

Por fim, como a aplicação já estava usando I18n para mensagens de erro do ActiveRecord (e alterar isso demandaria mais esforço), desativei esse comportamento do GetText:

# config/initializers/gettext_i18n_rails.rb
Rails.application.config.gettext_i18n_rails.use_for_active_record_attributes = false
Enter fullscreen mode Exit fullscreen mode

Processo de tradução

Para iniciar o processo de tradução, adicionei um texto usando o método do GetText:

<%= _("Nenhum resultado encontrado") %>
Enter fullscreen mode Exit fullscreen mode

Em seguida, executei a rake task:

rake gettext:find
Enter fullscreen mode Exit fullscreen mode

Essa rake task escaneia o projeto e adiciona as novas strings aos arquivos .po.

Depois, incluí a tradução correspondente no campo msgstr de cada arquivo .po:

 # locale/en/app.po

 msgid "Nenhum resultado encontrado"
-msgstr ""
+msgstr "No result found"

Enter fullscreen mode Exit fullscreen mode

Após atualizar as traduções, é importante rodar a rake task novamente. Isso garante que os arquivos edit.po sejam atualizados corretamente. Caso contrário, as alterações podem se misturar com novas strings adicionadas posteriormente, o que dificulta o controle de versões e a revisão das mudanças.

Features

Fallback automático

Se uma string não tiver tradução, ou se você esquecer de adicionar, o GetText retorna o valor original por padrão:

_("Nenhuma categoria encontrada")
# => Nenhuma categoria encontrada

Enter fullscreen mode Exit fullscreen mode

Também é possível fornecer um bloco. Se esse bloco for passado, seu conteúdo será retornado como valor padrão, o que permite definir um fallback mais explícito:

_("Não foi encontrada uma tradução") { "Texto alternativo" }
# => Texto alternativo
Enter fullscreen mode Exit fullscreen mode

Pluralização

A pluralização no GetText é semelhante à do I18n do Rails. Para que funcione corretamente, é necessário configurar a regra de plural de cada idioma nos arquivos .po.

No meu caso, os idiomas configurados ficaram assim:

# locale/en/app.po
- "Plural-Forms: nplurals=; plural=;\n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"

# locale/es/app.po
- "Plural-Forms: nplurals=; plural=;\n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"

# locale/pt_BR/app.po
- "Plural-Forms: nplurals=; plural=;\n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
Enter fullscreen mode Exit fullscreen mode

Depois disso, basta usar o método n_ passando o singular, o plural e o número.

n_("tarefa pendente", "tarefas pendentes", @total)
Enter fullscreen mode Exit fullscreen mode

Após rodar a rake task gettext:find , serão geradas as entradas necessárias nos arquivos .po . Com as chaves criadas, é só adicionar as traduções correspondentes.

Traduções dinâmicas

É possível interpolar variáveis dentro das strings normalmente. O conteúdo será exibido dinamicamente:

_("Publicado por %{username}") % { username: @user.username }
Enter fullscreen mode Exit fullscreen mode

Conclusão

Se você busca uma forma mais simples e direta de gerenciar traduções, vale a pena experimentar o GetText no seu projeto Rails. A integração é tranquila, o ganho em produtividade é real e você ainda pode manter o I18n do Rails para casos onde preferir.

Referências

Top comments (1)

Collapse
 
ivis1 profile image
Ivan Isaac

Ótima explicação sobre o uso do GetText no Rails, ficou bem claro! Só senti falta de uma comparação mais direta sobre eventuais desvantagens, como possíveis desafios na manutenção das traduções ou na colaboração com equipes maiores. Fora isso, o post está excelente!