A little short one today, but here goes.
The problem
User driven configuration combined with developer (hard-coded) configuration made for a difficult time to introduce translations to that area of the codebase. The issue was that some of the labels would be translated via the hard-coded configurations, but other instances would have the labels be possibly untranslated, because they’re user defined. Additionally, the internal components needed to be able to support translations when they were present, but also not force translations (due to migration timelines not lining up or because some configurations were for internal users in another area of the product which didn’t need translated).
The solution
Enter… try-translate.
So we knew that we would have a possibility of both translated strings and non-translated string. The configurations themselves needed to be JSON compatible, so we couldn’t just translate there (though, maybe eventually). So instead, I created a little helper that would attempt to translate the string and return either the translated string, or the original string.
tryTranslate(key: string) {
// Is the key a real translation key?
if (key.match(ourTranslationKeyRegex)) {
// Then we don't really care if the translation fails,
// because the failure message is important.
return this.translate(key);
}
// It must just be a non-translatable string
return key;
}
// Then we use it like...
tryTranslate('Not a translated string'); // Not a translated string
tryTranslate('mytranslationkey-pattern'); // The translated value
tryTranslate('mytranslationkey-pattern'); // Missing translation error, if can't be found
This does a couple things. First, the developer configurations would just include a translation key, which this helper will use to pass off to our translation service to get the proper translated value for the user’s locale. Fortunately for us, user configurations tend to extend the developer configurations, so if the label is translated in the extended developer configuration, the translation propagates down to the user configuration.
Secondly, if a team hasn’t translated their configurations yet, or if we allow users in the future to define their own label values, then this will gracefully handle that situation. It will throw an error if the parameter is a translation key, but the translation can’t be found. It will swallow the error and just return the parameter, if the parameter is not a translation key.
Everyone is happy, all the things are done, time for coffee.
