- Регистрация
- 1 Мар 2015
- Сообщения
- 1,481
- Баллы
- 155
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
Já com GetText, podemos escrever diretamente o texto original:
_("Nenhum resultado encontrado")
# => Nenhum resultado encontrado
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 e . 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:
LANGUAGE=xx rake gettext:add_language
Substitua xx pelo código do idioma desejado, por exemplo, en para inglês. A lista completa dos idiomas suportados está disponível .
rake gettext:find
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 , 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"
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
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
Processo de tradução
Para iniciar o processo de tradução, adicionei um texto usando o método do GetText:
<%= _("Nenhum resultado encontrado") %>
Em seguida, executei a rake task:
rake gettext:find
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"
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
Também é possível fornecer um . 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
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"
Depois disso, basta usar o método n_ passando o singular, o plural e o número.
n_("tarefa pendente", "tarefas pendentes", @total)
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 }
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
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
Já com GetText, podemos escrever diretamente o texto original:
_("Nenhum resultado encontrado")
# => Nenhum resultado encontrado
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 e . 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
Substitua xx pelo código do idioma desejado, por exemplo, en para inglês. A lista completa dos idiomas suportados está disponível .
- Para buscar traduções ausentes e adicioná-las aos arquivos .po:
rake gettext:find
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 , 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"
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
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
Processo de tradução
Para iniciar o processo de tradução, adicionei um texto usando o método do GetText:
<%= _("Nenhum resultado encontrado") %>
Em seguida, executei a rake task:
rake gettext:find
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"
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
Também é possível fornecer um . 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
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"
Depois disso, basta usar o método n_ passando o singular, o plural e o número.
n_("tarefa pendente", "tarefas pendentes", @total)
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 }
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