Localization and Translation in the Nexus Mods app
This page describes how to work with 'languages' in the App.
For the research info, see 07: Localization and Internationalisation
In the Nexus Mods app we use the industry standard Resource
(.resx
) files for porting
the App to different languages and cultures.
You can find them in Resources
folder for any project that contains UI elements.
NexusMods.App.UI
└── Resources
├── Language.de.resx // Autobahn (German)
├── Language.it.resx // Pizza (Italian)
├── Language.pl.resx // Pierogi (Polish)
└── Language.resx // Bri'ish innit
We create a .resx
file in every project for the base language, and additional .resx
files for any additional language you want to support.
Creating and Editing .resx
files requires a supported IDE such as Rider or Visual Studio
Adding Languages to a Project
- Create a folder called
Resources
, if it does not already exist. - Create a Resource file (right click folder,
Add
->Resources
), name itLanguage.resx
.
Resources/Language.resx
Doubleclicking this file in a supported IDE will bring you to the Resource Editor
,
which will allow you to edit the resources file.
Adding a New Language to the Project
This should be supported as a button in your IDE.
In Rider it is top left of 'Localization Manager', above the project listing.
If your IDE does not support this out of the box, create a Resource file using the naming convention:
Language.{culture}.resx
de
(German).
Full localized cultures are also supported, so de-de
(German, Germany) are supported.
Fixing Languages for Avalonia
For elements which may be referenced from the UI (Avalonia's .axaml
files), an additional step is required.
When you create a Resource
file from Within Rider, it will be set to internal
by default.
This is okay for code, but is not okay for XAML; as XAML needs those elements public.
To make these elements public, open the project's .csproj
file; find the .resx
file and change
ResXFileCodeGenerator
to PublicResXFileCodeGenerator
such that you will see:
<EmbeddedResource Update="Resources\Language.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Language.Designer.cs</LastGenOutput>
</EmbeddedResource>
You will then need to perform an action that would trigger a rebuild of Language.Designer.cs
.
This could be temporarily adding or renaming a key. These files are (unfortunately), not autogenerated as part of MSBuild (.NET build system).
How language is changed
The current locale for the app is set during startup, based on user configuration.
Runtime changes of the locale will not be immediately reflected in the UI, as most references are static.
Users will need to restart the App for the language change to fully take effect.
Overriding the Language at Boot Time
You can change the locale in AppConfig.json
file.
"LauncherSettings": {
"LocaleOverride": ""
}
For example, you can set "LocaleOverride": "de"
for your App to display in German.
This file is copied to upon build.
Switching a Language
Language can be switched at runtime with the following code:
Thread.CurrentThread.CurrentUICulture = new CultureInfo(/* locale */);
Where locale
is a string representing the locale, e.g. it
for Italian.
We run this code at startup.
This will not update the UI. Users will need to be asked to restart the App for the language change to take effect.
Using Localized Text
Tells you how to use localized text in the App.
Reference Text from C#
Basic Referencing
You can reference strings via the Language
static class.
var text = Language.MyGames
In some cases your language may default to English.
This can happen if the code is ran before the locale is set at startup; this should not however be a common occurrence.
Formatted Text
In some cases, you might have to use string.Format
to inject parameters into the text:
// Language.Hello is "Hello {0}"
string.Format(Language.Hello, user)
Reference from AXAML
In AXAML, you can reference localized string using static compile safe binding as follows:
<TextBlock Text="{x:Static resources:Language.SearchBox__Search}"/>
If formatting is required, please do so in the code behind.
Reference from XAML (stylesheets)
Avalonia .axaml
themes cannot reference localised resources.
The theme files are loaded before the language can be set at startup; and there is currently no way to manually trigger a refresh. So the default english strings will; be used.
If you run into this problem, set the strings inside your .axaml.cs
views.
This might lead to some loss of convenience from styled elements use, but ensures compile time safety.