DEV Community

Miller Correa
Miller Correa

Posted on

How to use gettext in phoenix?

Así se usa Gettext:

<h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
Enter fullscreen mode Exit fullscreen mode

Errores en Gettext

Extraer las traducciones

mix gettext.extract
Enter fullscreen mode Exit fullscreen mode

Mezclar las traducciones extraídas con las que ya tengo (para todos los lenguajes)

mix gettext.merge priv/gettext
Enter fullscreen mode Exit fullscreen mode

Pluralización

https://phrase.com/blog/posts/i18n-for-phoenix-applications-with-gettext/

Este comando de pluralización genera errores cuando se le pasa un numero menor que 1 ya que no existen plurales para 0 ó numeros negativos y sintacticamente no tiene sentido

Ejemplo

## Llamado de un texto en singular con número 1
<%= ngettext("Total salary", "Total salaries", 1) %> #-> Total Salaries
## Llamado de un texto plural con número 2 ó mas en este caso ese numero se interpola

<%= ngettext("Total salary", "Total salaries", 2) %> #-> Total Salaries
Enter fullscreen mode Exit fullscreen mode

Archivos .po en plural

msgid "Total salary"
msgid_plural "Total %{count} salaries"
msgstr[0] "Total Salary"
msgstr[1] "Total Salaries"
Enter fullscreen mode Exit fullscreen mode

Ventajas de manejar Gettext sin nomenclatura

  1. La traducción al inglés ya está hecha en el código.
  2. El manejo de mayusculas y minusculas no depende de usar prefijos(ejm: Text ó Label), si no de la palabra correspondiente, si se usa una palabra en mayuscula la primera esta va a salir así como se escriba

    1. Con Nomenclatura
    msgid "LabelDeductions"
    msgstr "Deducciones"
    
    msgid "textDeductions"
    msgstr "deducciones"
    
    1. Sin nomenclatura
    msgid "Deductions"
    msgstr "Deducciones"
    
    msgid "deductions"
    msgstr "deducciones"
    

    Nota:

    <%= gettext("house") %>
    <%= gettext("House") %>
    

    Si se tiene lo anterior en el código y se realiza una traducción como

    msgid "house"
    msgstr "casa"
    

    Al extraer y mezclar traducciones, Gettext infiere automáticamente la otra traducción sin tener en cuenta las mayúsculas y regresa(con la palabra fuzzy).

    #, elixir-format, fuzzy
    msgid "House"
    msgstr "casa"
    
    

    Lo anterior permite que el desarrollador no tenga que estar pendiente de las mayusculas que están en el documento.

  3. Se optimiza el tiempo de codificado, las traducciones se pueden hacer de manera atemporal.

    El hecho de ser atemporales y sin contexto se refiere a que “una persona sin tener el contexto ó la información de donde se muestran estos mensajes en la aplicación puede traducirlos ó crear una mejor traduccion.”

    msgid "LabelDaysGrantedVacation"
    msgstr "Días otorgados de vacaciones"
    
    ## Reemplaza con
    
    msgid "Vacation days granted"
    msgstr "Días otorgados de vacaciones"
    
    ## La traducción en ingles se torna opcional, ya que el usuarió visualizara
    ## "Vacation days granted" y no "LabelDaysGrantedVacation" al igual que el 
    ## programador que vera un texto mas entendible
    
```bash
msgid "TextInfoAbbRUTAbbDIAN"
msgstr "Para ingresar la información personal de su nuevo trabajador, puede ingresar el archivo (PDF) del Registro Único Tributario (RUT) descargado de la DIAN (maximo de treinta días de antiguedad). Recuerde que lo puedes descargar del sistema Muisca de la DIAN "

msgid "To enter the personal information of your new worker, you can enter the file (PDF) of the Single Tax Registry (RUT) downloaded from the DIAN (maximum thirty days old). Remember that you can download it from the DIAN Muisca system "
msgstr "Para ingresar la información personal de su nuevo trabajador, puede ingresar el archivo (PDF) del Registro Único Tributario (RUT) descargado de la DIAN (maximo de treinta días de antiguedad). Recuerde que lo puedes descargar del sistema Muisca de la DIAN "
```
Enter fullscreen mode Exit fullscreen mode
  1. Las variables empiezan a tomar sentido

    #Con nomenclatura
    msgid "LabelApplyDecree%{Decree}%{YearDecree}"
    msgstr "Aplica para decreto %{Decree} del año %{YearDecree}"
    
    #Sin nomenclatura
    msgid "Applies to decree %{NumberDecree} of %{YearDecree}"
    msgstr "Aplica para decreto %{Decree} del año %{YearDecree}"
    
  2. Las traducciones se pueden compartir entre proyectos,

    El comando mix gettext.merge priv/gettext no borra las traducciones que ya se tienen en el archivo, por el contrario las mezcla é intenta predecir las posibles traducciones, si no tiene una coincidencia perfecta, marca la traducción como "dirtty", una vez que se modifica por parte de un programador manualmente, la establece como limpia automaticamente para la proxima extracción.

  3. Gettext utiliza la distancia de Jaro para determinar si dos palabras o frases son similares y de esta manera infiere la traducción que marca como fuzzy

Plurales, porque complicarse?

Sí, es más complejo usar plurales en forma adecuada en Gettext que utilizar condicionales en elixir y usar:

<%= if numero_casas > 1 %> 
    <%= "Las Casas" %>
<% else %>
    <%= "La Casa" %>
<% end %>

Enter fullscreen mode Exit fullscreen mode

Que usar:

<%= ngettext("La Casa", "Las Casas", numero_casas) %>
Enter fullscreen mode Exit fullscreen mode

Si bien tiene una curva de aprendizaje su uso, el código es más legible y estas traducciones nos serviran en otros proyectos

Untitled

De esta manera, si algo no funciona siempre va a tener una lectura real y clara

Ventaja traducción con los plurales

Los id singulares son diferenciados de los Id plurales


#Los Id no chocan con los Id plurales
msgid "TextDeductions" #mismo ID en singular
msgstr "deducciones"

msgid "TextDeduction"
msgid_plural "TextDeductions" #mismo ID en plural
msgstr[0] "deduccion"
msgstr[1] "deducciones"
Enter fullscreen mode Exit fullscreen mode

Desventajas

Los plurares NO incluyen el termino que se debe utilizar cuando se tienen 0 items solo cuando se tiene uno ó muchos por ejemplo

Sin filtros # No hay forma de aplicarlo
1 Filtro
2 Filtros
3 Filtros
Enter fullscreen mode Exit fullscreen mode

Los plurales se tornan más largos,

ngettext("Deduction", "Deductions", 2)

Los archivos mezclados primero se deben esx

mix gettext.merge priv/gettext/en/LC_MESSAGES/default2.po priv/gettext/en/LC_MESSAGES/default.po

Mezclar 2 archivos .po

mix gettext.merge  priv/gettext/en/LC_MESSAGES/default2.po priv/gettext/en/LC_MESSAGES/default.po
Enter fullscreen mode Exit fullscreen mode

Para test

<%= gettext("The house is very pretty") %>

<%= gettext("The house") %>

<%= gettext("is very pretty") %>

<%= gettext("is very %{house}") %>

<%= gettext("house") %>

<%= gettext("House") %>

Mayusculas y minusculas

Gettext es CaseSensitive debido a que en algunos lenguajes una palabra en mayuscula es diferente a una palabra en minúscula, por lo tanto tiene esta diferencia y la solucion es tratar ambos casos como corresponde además facilita el trabajo del progrmador, esto es una ventaja y una desventaja en realidad que se soluciona con gettext extract.

Gettext con variables en el string

<% text_action = if @action == "edit", do: "LabelEdit%{Object}" , else: "LabelCreate%{Object}" %>
<span class="uk-text-capitalize uk-font-size-15"><%= Gettext.gettext(WebPortalBillingWeb.Gettext, text_action, Object: gettext("TextClient")) %></span>
Enter fullscreen mode Exit fullscreen mode

Usar Gettext dentro de controladores ó liveview

Es importante pasar *NombreApp**Web**.Gettext en el primer parámetro para que funcione el gettext, tenga en cuent que el módulo es NombreApp**Web** con Web al final.*

Gettext.gettext(NombreAppWeb.Gettext, "LabelRestrictionForDSAdquisitionsNational%{Object}", Object: "#{id_type}")
Enter fullscreen mode Exit fullscreen mode

Usando con un contexto específico “errors” es decir, el archivo errors.po

Gettext.dgettext(NombreAppWeb.Gettext, "errors", "Message")

#Si el mensaje esta en una variable puede definir un valor por defecto con || 
#ya que si pasa nil a la función esta fallara

Gettext.dgettext(NombreAppWeb.Gettext, "errors", (nil || "Default Message")
Enter fullscreen mode Exit fullscreen mode

Como hacer una traduccion con un valor que cambia?

Esto no funciona, nativamente pero se puede intentar sacar las variables aparte con una función para hacer el matching.

Suponga que del back llegan los siguientes errores

"Son 300 pesos" 
"Son 650 pesos" 
"Son 700 pesos" 
Enter fullscreen mode Exit fullscreen mode

¿Es posible generar un gettext que traduzca este texto mediante un unico id?

Puede intentar usar named_captures para sacar aparte la lista de numeros que vienen en un texto

Regex - Elixir v1.12.3


Enter fullscreen mode Exit fullscreen mode
#Algo como esto
msgid "Son %{Number} pesos"
msgstr "Is %{Number} pesos"
#generara algo como esto
"Is 300 pesos"
Enter fullscreen mode Exit fullscreen mode

Gettext.gettext(WebPortalBillingWeb.Gettext, "Is 700 pesos")
Enter fullscreen mode Exit fullscreen mode

Top comments (0)