gt-react@10.18.0
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 Entries | Translation 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 Entries | Translation 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 Entries | Translation Entries |
|---|---|
| I am tired | Estoy 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.