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 will generate a separate translation entry for every different context.
Motivation
We made an early mistake in our context system. The derivation system uses a one-to-one mapping between the content from 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 output a single translation. This means that if you were to create n source entries then you would have n translation entries. However, we did not account for a simple fact: given just the content from 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 necessary to translate all of the source entries.
We can break this into three cases: one-to-one, many-to-one, and one-to-many. It is important to realize 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
For every source entry, we can map to a translation entry, and the size of the source set is greater than the size of the translation set. For example, we can go from English to Mandarin as English follows pluralization rules, while Mandarin does not. This means in Mandarin, we can represent multiple source entries with a single translation entry.
| Source Entries | Translation Entries |
|---|---|
| I have cat. | 我有只猫。 |
| I have cats. |
Case 3: One-to-many mapping
For every source entry, we can map to one or multiple translation entries. For example, Spanish respects 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 leveraging our context system with our derive system. The user 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 for resolving 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) satisfies 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.