Strings and Translations
The main purpose of Tlumach is to provide localized / translated strings picked from translation files in a handy way.
Each string is identified by a string key; translation files are sets of key-value pair in different formats. Each string together with its key makes a translation unit.
Keys are case-insensitive and should be valid identifiers in .NET format. A valid identifier must start with a letter or '_' (underscore) which may be followed by a zero or more letters, digits, and underscores:
These are the sample valid keys:
valid_key=text
_validKey=text
_1_key=text
When Generator is used, keys become variable names, so if you use some analyzer that enforces the style of variable names, be sure that your keys follow that style at least in the default file.
Groups of Strings
If a file format supports grouping, translation units can be grouped. When a translation unit belongs to a group, the name of the group becomes a prefix of the key, joined with the key using '.' (dot).
E.g., you can have the "greetings" group in the translation file, with "hello" and "goodbye" entries in it:
[greetings]
hello=Hello
goodbye=Bye
These units can be accessed by using the "greetings.hello" and "greetings.goodbye" keys respectively. When Generator is used, groups become nested classes in the main class being generated, i.e., "greetings" will be a nested class, and "hello" and "goodbye" will be variables in this class.
Groups may be nested:
[greetings]
hello=How do you do!
goodbye=Goodbye!
[greetings.Informal]
hello=Hello
goodbye=Bye
This configuration will give you the "greetings" class and the "Informal" class inside the "greetings" class. The first two units will be "greetings.hello" and "greetings.goodbye", and the last two will be "greetings.Informal.hello" and "greetings.Informal.goodbye" respectively.
Regular and Templated Strings
If a string is not templated, i.e., does not contain placeholders, Tlumach provides this string as is. If you use generated translation units, you can access the text using the instance of TranslationUnit that has the name equal to the key of the needed string. If you work directly with TranslationManager, use one of the GetValue() methods (GetValue(string), GetValue(string, CultureInfo), GetValue(TranslationConfiguration, string, CultureInfo)) to obtain an instance of TranslationEntry and read the value of the Text property.
If a string is templated, an application can retrieve it from the translation manager as a template and handle the placeholders as it likes, or the application can use the capabilities of Tlumach to process templates and fill the template with actual values.
To obtain the template when using Generator, the application can call the GetValueAsTemplate(CultureInfo) method.
When working directly with TranslationManager, the application can call one of the GetValue() methods (GetValue(string), GetValue(string, CultureInfo), GetValue(TranslationConfiguration, string, CultureInfo)) that return an instance of TranslationEntry and read the value of the Text property. To let Tlumach process the template, you can inspect the IsTemplated property of this entry and if it is true, use one of the ProcessTemplatedValue() methods (ProcessTemplatedValue(CultureInfo, TextFormat, IDictionary<string, object?>), ProcessTemplatedValue(CultureInfo, TextFormat, OrderedDictionary), ProcessTemplatedValue(CultureInfo, TextFormat, object), ProcessTemplatedValue(CultureInfo, TextFormat, params object?[])) to fill the template with the data.
Current and Other Locales
TranslationManager has a CurrentCulture property which is used as a default culture, for which translation units are retrieved.
This CurrentCulture property is useful first of all in UI applications where XAML properties are bound to generated translation units: the text provided to the bound controls is defined by the value of this property.
If you are using one of the methods for retrieval of translation units mentioned above in their overloads that don't include a culture, the value of CurrentCulture is used there too.
To change the language of the UI in your XAML-based project, change the value of CurrentCulture. This will notify the bindings and also cause the OnCultureChanged event to fire.
Overriding Translation Files
Sometimes, it is necessary to provide a specific phrase regardless of its presence in a translation file. Maybe, the string is completely missing from the translation, or, maybe, your application configuration allows administrators to define some messages for their users.
To address these needs, TranslationManager includes several events:
- OnTranslationValueNeeded is fired when TranslationManager receives a request for a translation unit before it attempts to locate the unit in the translation files. You can provide a unit by assigning a value to Entry, Text, or EscapedText properties of the event arguments class (TranslationValueEventArgs).
- OnTranslationValueFound is fired when TranslationManager finds the needed translation unit. Your application has a chance to override the value. This can be done by replacing a value in Entry, or by assigning a value to Text or EscapedText properties of the event arguments class (TranslationValueEventArgs).
- OnTranslationValueNotFound is fired if TranslationManager does not find the needed translation unit. You can provide a unit by assigning a value to Entry, Text, or EscapedText properties of the event arguments class (TranslationValueEventArgs).