Back

gt-react@10.18.0

Ernest McCarter avatarErnest McCarter
gt-reactderivecontexti18n

Overview

This release adds support for derivable context values. Similar to our derive system for content, you can now add a derive invocation to a context property. This generates a separate translation entry for each distinct context.

Motivation

We made an early mistake in our context system. The derivation system uses a one-to-one mapping between the content of a source entry and a translation: one source creates one translation. This works well with our existing translation system. It expects to take a source as input and return a single translation. This means that if you were to create n source entries, you would have n translation entries. However, we did not account for one simple fact: given only the content of a source entry, there may be multiple necessary translations.

Understanding the problem

Imagine that we have the set of source entries. This set represents all of the source entries that we have extracted from a translation invocation. Then we have an ideal set of translation entries. This set represents an ideal set of all the translations that would be needed to translate all of the source entries.

We can break this down into three cases: one-to-one, many-to-one, and one-to-many. It is important to realise that there is not always a one-to-one mapping between the source and translation sets.

Case 1: One-to-one mapping

For every source entry, we can map to a unique translation entry.

Source EntriesTranslation Entries
The boy is beautiful.El niño es hermoso.
The girl is beautiful.La niña es hermosa.

Case 2: Many-to-one mapping

Each source entry can be mapped to a translation entry, and the source set is larger than the translation set. For example, this applies when going from English to Mandarin, because English follows pluralisation rules whereas Mandarin does not. This means that in Mandarin, multiple source entries can be represented by a single translation entry.

Source EntriesTranslation Entries
I have cat.我有只猫。
I have cats.

Case 3: One-to-many mapping

For each source entry, we can map to one or more translation entries. For example, Spanish distinguishes between masculine and feminine agreement where English does not. We can therefore end up with two translation entries for the same source entry.

Source EntriesTranslation Entries
I am tiredEstoy cansado
Estoy cansada

This is the case that we did not account for in the initial implementation. We had assumed that there would always be a one-to-one mapping between source entries and translations.

Solution

This issue can be solved by using our context system together with our derive system. Users can choose a context value at runtime to disambiguate between two or more translation entries.

condition
  ? gt("I am tired", { $context: "inflect as masculine" })
  : gt("I am tired", { $context: "inflect as feminine" })

We can then combine this with a derive invocation to embed runtime logic that resolves the correct translation entry.

gt("I am tired", { $context: derive(
  condition ? "inflect as masculine" : "inflect as feminine"
)})

This will now generate two translation entries:

"I am tired" -> "Estoy cansado"
"I am tired" -> "Estoy cansada"

This (1) covers all necessary translation cases and (2) allows the user to disambiguate between the two translation entries at runtime.

In summary

Derivation for context addresses a fundamental gap in our translation model: the inability to represent one-to-many mappings between source and translation entries.