Atrás

gt-next@6.8.0

Ernest McCarter avatarErnest McCarter
gt-reactgt-nextgtx-cliv6.8.0statictranslationi18n

Descripción general

A menudo observamos que, cuanto más madura es una base de código, más fragmentado queda el contenido. Las oraciones terminan dispersas entre funciones, utilidades, lógica y servicios.

function getSubject(gender) { 
  return gender === "male" ? "niño" : "niña" 
}
function getObject(toy, gender) { 
  return toy === "pelota" ? "pelota" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <>
      <p>
        El/La hermoso/a {getSubject(gender)} juega con el/la {getObject(toy, gender)}.
      </p>
    </>
  )
}

Cuando inevitablemente llega el momento de internacionalizar, los desarrolladores descubren que se han dejado sin salida. Aplicar cosas como la concordancia, la conjugación y los cambios en el orden de las palabras en múltiples archivos no es manejable sin una refactorización importante. Tradicionalmente, esto significaba extraer manualmente todas las permutaciones posibles de cada frase y añadirlas a un diccionario de traducciones.

En gt-next 6.8.0, redoblamos nuestra apuesta por la idea de que una biblioteca de i18n sólida se adapta a la base de código, y no al revés. Aunque gt-next ya traduce contenido inline, carece de dos características fundamentales de una biblioteca de este tipo: (1) compatibilidad con la fragmentación de oraciones y (2) contenido reutilizable que también preserve la concordancia, la conjugación o los cambios en el orden de las palabras.

Estamos incorporando el componente <Static> para permitir llamadas a funciones estáticas directamente dentro de las traducciones.

function getSubject(gender) { 
  return gender === "male" ? "niño" : "niña" 
}
function getObject(type, gender) { 
  return type === "pelota" ? "pelota" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <T>
      <p>
        <Static>{getSubject(gender)}</Static> hermoso juega con <Static>{getObject(toy, gender)}</Static>.
      </p>
    </T>
  )
}

Consideraciones importantes

Dicho esto, insistimos encarecidamente en que uses el componente <Static> con cuidado y criterio. El componente <Static>, aunque potente, también puede provocar aumentos significativos en el número de entradas de traducción. Si se usa de forma incorrecta, esto podría tener efectos negativos en los tiempos de carga de una aplicación.

Cómo usar <Static>

Al igual que los componentes <T> y <Var>, el componente <Static> es una marca que le indica a la herramienta CLI dónde debe y no debe buscar contenido traducible. Le indica a la herramienta CLI que desreferencie una llamada de función dentro de las etiquetas <Static> y catalogue todos los posibles contenidos que devuelve esa función. Trata cada declaración de retorno como si tuviera un componente <T> envolviéndola.

Una vez que la herramienta CLI ha encontrado todas las posibles salidas de una llamada de función, crea una entrada de traducción independiente para cada salida posible. Por ejemplo, el siguiente código crea dos entradas de traducción independientes: "The boy is beautiful" y "The girl is beautiful". Como existe una entrada de traducción diferente para cada salida posible, podemos admitir la concordancia, la conjugación y el orden de palabras en una frase fragmentada: "El niño es hermoso" y "La niña es hermosa".

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function Component({ gender }) {
  return (
    <T>
      El <Static>{getSubject(gender)}</Static> es hermoso.
    </T>
  )
}

Limitaciones y mejoras futuras

Multiplicación

Como se mencionó anteriormente, el componente <Static>, si se utiliza con demasiada frecuencia, puede generar una gran cantidad de entradas de traducción, lo que podría tener un impacto negativo en el rendimiento de los tiempos de carga. Por ejemplo, considera un componente con dos componentes <Static>, cada uno envolviendo una invocación de función con dos posibles resultados. En este caso, se crean cuatro entradas de traducción. Cada componente <Static> adicional multiplica el número de traducciones por el número de resultados posibles de cada llamada de función.

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function getObject(toy) { 
  return toy === "ball" ? "ball" : "crayon"
}
function Component({ gender, toy }) {
  return (
    <T>
      <Static>{getSubject(gender)}</Static> juega con el <Static>{getObject(toy)}</Static>.
    </T>
  )
}

Sintaxis

Es importante tratar cada instrucción return como si tuviera un componente <T> envolviéndola. Cualquier variable o llamada de función dinámica debe seguir estando envuelta en componentes <Var>.

Actualmente, <Static> solo admite llamadas de función como elementos hijos, pero en el futuro podrá admitir expresiones más complejas. A partir de gt-next 6.8.0, se admite la siguiente sintaxis para funciones estáticas:

function getExamples(key) {
  switch (key) {
    case "string, number, and boolean literals":
      if (condition1) {
        return "El niño"
      } else if (condition2) {
        return 22
      } else {
        return true
      }
    case "jsx expressions":
      return (
        <>
          Hola, <Static>{getTitle(title)}</Static>. ¿Cómo estás, <Var>{name}</Var>?
        </>
      );
    case "ternary operators":
      return condition ? "El niño" : "La niña"      
    case "function calls":
      return otherStaticFunction();
  }
}

Conclusión

gt-next 6.8.0 introduce el componente <Static> como solución a la fragmentación de oraciones sin sacrificar la cobertura de traducción ni una correcta concordancia gramatical.