Autotransl - guiled/LRE GitHub Wiki
Automatic translation
LRE allows you to automatically translate component values and table data using Let's Role's i18n system by setting lre.autoTransl(true) in your system script.
Problem description
When building multilingual character sheets, you often need to translate text strings throughout your code. The following code shows a common pattern where you need to manually call the translation function _() everywhere:
const raceName = sheet.get('race').value();
const translatedRace = _(raceName);
log('Selected race: ' + translatedRace);
const skillNames = sheet.get('skills').value();
const translatedSkills = {};
Object.keys(skillNames).forEach(function(key) {
translatedSkills[key] = _(skillNames[key]);
});
// Or when working with table data
Tables.get('items').each(function(item) {
const translatedName = _(item.name);
const translatedDescription = _(item.description);
log(translatedName + ': ' + translatedDescription);
});
This approach requires you to:
- Remember to call
_()on every string that needs translation - Manually translate nested objects and arrays
- Handle translation for table data separately
- Write repetitive translation code throughout your script
Some systems have dozens or even hundreds of _() calls scattered throughout the code, making it harder to read and maintain. Moreover, you can lose time coding and debugging because you forgot to add _() in some places.
LRE solution = lre.autoTransl(true)
LRE offers a flag that allows you to automatically translate all non-numeric string values from components, tables, objects, and arrays. This works recursively, so nested data structures are automatically translated as well. You don't need to use _() manually anymore.
lre.autoTransl is set to false by default and can be changed anywhere in your system code. Please note that any code run before lre.autoTransl(true) won't have any automatic translations.
const init = lre(function (sheet) {
lre.autoTransl(true);
// Component values are automatically translated
const raceName = sheet.get('race').value();
log('Selected race: ' + raceName); // Already translated!
// Objects are automatically translated recursively
const skills = sheet.get('skills').value();
// All string values in the skills object are now translated
// Arrays are automatically translated recursively
const itemNames = sheet.get('itemList').value();
// All string values in the array are now translated
});
What gets translated?
Only non-numeric strings are translated. This means:
-
✅ Regular text strings are translated:
lre.autoTransl(true); const text = lre.value("Strength"); // Returns: translated version (e.g., "Force" in French) -
✅ String values in objects are translated:
lre.autoTransl(true); const data = { name: "Sword", type: "Weapon", damage: "1d6" }; const translated = lre.value(data); // Result: { name: "Épée", type: "Arme", damage: "1d6" } // Note: "1d6" is not translated because it's numeric -
✅ String values in arrays are translated:
lre.autoTransl(true); const items = ["Sword", "Shield", "Potion"]; const translated = lre.value(items); // Result: ["Épée", "Bouclier", "Potion"] -
❌ Numeric strings are NOT translated (they are converted to numbers if
autoNumis enabled):lre.autoTransl(true); const level = lre.value("5"); // Returns: 5 (number, not translated) const damage = lre.value("1d6"); // Returns: "1d6" (contains numbers, not translated) -
❌ Empty strings are NOT translated:
lre.autoTransl(true); const empty = lre.value(""); // Returns: "" (unchanged) -
❌ Numbers, objects, and arrays themselves are NOT translated (only their string contents):
lre.autoTransl(true); const num = lre.value(42); // Returns: 42 (unchanged) const obj = lre.value({}); // Returns: {} (unchanged, but string values inside would be) const arr = lre.value([1, 2, 3]); // Returns: [1, 2, 3] (unchanged, but string values inside would be)
Automatic translation with components
When lre.autoTransl(true) is enabled, component values are automatically translated when you call component.value():
lre.autoTransl(true);
// Component value is automatically translated
const race = sheet.get('race').value();
log(race); // Output: translated race name (e.g., "Elf" becomes "Elfe" in French)
// Works with all component types that return strings
const characterName = sheet.get('characterName').value(); // Translated if it's a string
const description = sheet.get('description').value(); // Translated if it's a string
Automatic translation with tables
The flag allows automatic translation of table data as well. When you access table data, all non-numeric string values are automatically translated:
lre.autoTransl(true);
// Table data is automatically translated
Tables.get('races').each(function(race) {
log(race.name); // Already translated!
log(race.description); // Already translated!
log(race.bonus); // Not translated if it's numeric (e.g., "+2")
});
// Using DataProvider methods
const races = Tables.get('races');
const translatedNames = races.select('name').providedValue();
// All race names in the result are automatically translated
Automatic translation with objects and arrays
LRE automatically translates string values recursively in objects and arrays:
lre.autoTransl(true);
// Nested objects are translated recursively
const characterData = {
name: "Gandalf",
race: "Wizard",
stats: {
strength: "12",
class: "Mage"
}
};
const translated = lre.value(characterData);
// Result:
// {
// name: "Gandalf" (translated if translation exists),
// race: "Magicien" (translated),
// stats: {
// strength: 12 (converted to number if autoNum is enabled),
// class: "Mage" (translated)
// }
// }
// Arrays are translated recursively
const skills = ["Acrobatics", "Athletics", "Stealth"];
const translatedSkills = lre.value(skills);
// Result: ["Acrobatie", "Athlétisme", "Furtivité"]
Combining autoNum and autoTransl
You can use both lre.autoNum(true) and lre.autoTransl(true) together. In this case, numeric strings are converted to numbers first, and non-numeric strings are translated:
lre.autoNum(true);
lre.autoTransl(true);
const data = {
level: "5", // Converted to number: 5
name: "Character", // Translated: "Personnage"
damage: "1d6", // Not numeric, not translated: "1d6"
type: "Warrior" // Translated: "Guerrier"
};
const result = lre.value(data);
// Result: { level: 5, name: "Personnage", damage: "1d6", type: "Guerrier" }
Translation priority
When both autoNum and autoTransl are enabled, the priority is:
- First: Check if the string is numeric → convert to number (if
autoNumis enabled) - Then: If not numeric → translate the string (if
autoTranslis enabled)
This means numeric strings are never translated, and non-numeric strings are never converted to numbers.
Missing translations
If a translation doesn't exist in your i18n system, the original string is returned unchanged. This allows you to gradually add translations without breaking your code:
lre.autoTransl(true);
// If "Sword" has a translation → returns translated version
// If "Sword" has no translation → returns "Sword" (unchanged)
const weapon = lre.value("Sword");
LRE tracks untranslated strings internally, which can be useful for identifying missing translations during development.
log(lre.i18n.getUntranslated())
Complete example
Here's a complete example showing automatic translation in action:
const init = lre(function (sheet) {
// Enable automatic translation
lre.autoTransl(true);
// Component values are automatically translated
sheet.get('race').on('update', function(raceComponent) {
const race = raceComponent.value(); // Already translated!
log('Selected race: ' + race);
});
// Table data is automatically translated
const items = Tables.get('items');
items.each(function(item) {
// All string values are already translated
log(item.name + ': ' + item.description);
});
// Complex nested data is automatically translated
const characterData = sheet.get('characterData').value();
// All string values in the object (and nested objects) are translated
// Populate a choice with translated values
const races = Tables.get('races');
sheet.get('raceChoice').setChoices(races.select('name'));
// Race names in the choice are automatically translated
});
When to use autoTransl
Use lre.autoTransl(true) when:
- ✅ You want to support multiple languages in your character sheet
- ✅ You have many strings that need translation
- ✅ You want to avoid manually calling
_()everywhere - ✅ You want automatic translation of table data
- ✅ You want translation to work recursively in objects and arrays
Don't use lre.autoTransl(true) when:
- ❌ Your character sheet is single-language only
- ❌ You need fine-grained control over which strings are translated
- ❌ You want to translate only specific strings manually
Performance note
Automatic translation adds a small overhead to value retrieval, but it's generally negligible. The translation lookup is fast, and the convenience of automatic translation usually outweighs the minimal performance cost.