Localization / Translation approaches
Posted: 25 Jan 2019, 22:46
Hi guys,
I'm starting my work on CryoFall localization soon and researching the localization approaches. I've checked the forums (outdated topic) and NoesisGUI localization sample on Github and here are my thoughts on each approach I've thought about:
1. NoesisGUI approach from the sample which is using {Binding MyLocalizationKey} is not applicable for applications using MVVM pattern as DataContext is already used for ViewModels. Moving localization text data into the ViewModels is not a great idea as in many cases the text entries could be reused in multiple places but ViewModel is usually done for a few specific cases - also I don't like the idea of polluting the ViewModels with localization stuff.
2. XAML Markup extensions (example implementation for localization):
could be a good idea to inject localization but it's not supported in NoesisGUI C# API (#1401).
3. Approach with attached properties (custom localization service) and strong-typed enum usage:
I've used it in the previous game (VoidExpanse) and I don't like it for multiple reasons:
4. x:Static approach to reference C# const string:
alas, it's not yet supported (#1035).
5. Simply define all localizable data in a XAML resource dictionary (one per language, e.g. "UI.en_us.xaml" for US English, "UI.ru_ru.xaml" for Russian, etc) and use StaticResources to reference localizable strings (and probably other resources such as images). Depending on the language the application can (re)load NoesisGUI and provide the localization resource dictionary for the selected language.
I see a potential issue with XAML loading as the localization strings resource dictionary should be loaded as a global resource dictionary (like in WPF App-wide resources) before loading any other resource dictionaries and controls which require these strings but this feature is not yet supported (#1379).
This approach is also requires some extra effort as I don't want to edit localization data by hand - it's expected to be delivered in CSV format to the game publisher for translation so an import-export tool is required.
My current best idea - if I could use x:Static in XAML to reference C# const string entries it will be sufficient for XAML localization and I will not need to spend extra time on implementing tooling for XAML localization import/export. I can just write the required C# localization tooling (which will use Roslyn compiler to rewrite string constants and localizable C# properties - something I can do relatively easily as the C# code is already pre-processed and compiled by the game with Roslyn!). So with this approach, it will work for both C# and XAML localization (as XAML will reference C# string const's) and will save me a lot of time and effort. But it requires support from NoesisGUI (#1035) I'm curious if it could be done before NoesisGUI 2.2 release.
Would love to hear your ideas regarding the better localization approach.
Regards!
I'm starting my work on CryoFall localization soon and researching the localization approaches. I've checked the forums (outdated topic) and NoesisGUI localization sample on Github and here are my thoughts on each approach I've thought about:
1. NoesisGUI approach from the sample which is using {Binding MyLocalizationKey} is not applicable for applications using MVVM pattern as DataContext is already used for ViewModels. Moving localization text data into the ViewModels is not a great idea as in many cases the text entries could be reused in multiple places but ViewModel is usually done for a few specific cases - also I don't like the idea of polluting the ViewModels with localization stuff.
2. XAML Markup extensions (example implementation for localization):
Code: Select all
<TextBlock Text="{loc:Traslate MyLocalizationKey}" />
3. Approach with attached properties (custom localization service) and strong-typed enum usage:
Code: Select all
<TextBlock locService.Localize="MyLocalizationEnum_SomeKey" />
- it's too verbose/lengthy
- the attached property service should recognize various controls and know how to properly inject the localization (e.g. in case of TextBlock it should use the Text property but in case of ContentControls it should use Content property). It also means that injecting localization into tooltip is hard (all localizatible tooltips should be redone as explicit Tooltip entry with a TextBlock using the localization service).
- there could be only a single enum type (though it's possible to use x:Static to support different enum types (which is already supported) but then the syntax is even more lengthy!)
- not compatible with {Binding StringFormat=...} which is a very useful feature
- introduces a level of indirection as we cannot simply Ctrl+Click to navigate to the original text - the original text is stored in a separate file (could be a simple text file as in VoidExpanse) where each string has a key matching the enum key (which is also very fragile and error-prone - easy to forget to rename the key in text file after renaming the key in enum, etc).
4. x:Static approach to reference C# const string:
Code: Select all
<TextBlock Text="{x:Static MyClass.MyTextConstName}" />
5. Simply define all localizable data in a XAML resource dictionary (one per language, e.g. "UI.en_us.xaml" for US English, "UI.ru_ru.xaml" for Russian, etc) and use StaticResources to reference localizable strings (and probably other resources such as images). Depending on the language the application can (re)load NoesisGUI and provide the localization resource dictionary for the selected language.
I see a potential issue with XAML loading as the localization strings resource dictionary should be loaded as a global resource dictionary (like in WPF App-wide resources) before loading any other resource dictionaries and controls which require these strings but this feature is not yet supported (#1379).
This approach is also requires some extra effort as I don't want to edit localization data by hand - it's expected to be delivered in CSV format to the game publisher for translation so an import-export tool is required.
My current best idea - if I could use x:Static in XAML to reference C# const string entries it will be sufficient for XAML localization and I will not need to spend extra time on implementing tooling for XAML localization import/export. I can just write the required C# localization tooling (which will use Roslyn compiler to rewrite string constants and localizable C# properties - something I can do relatively easily as the C# code is already pre-processed and compiled by the game with Roslyn!). So with this approach, it will work for both C# and XAML localization (as XAML will reference C# string const's) and will save me a lot of time and effort. But it requires support from NoesisGUI (#1035) I'm curious if it could be done before NoesisGUI 2.2 release.
Would love to hear your ideas regarding the better localization approach.
Regards!