One of my favorite tools for Internationalization (or localization as it is also been called) is the Multilingual App Toolkit. It really makes it possible to manage multiple languages easily and is a top notch tool.
I recently started using a Portable Class Library to share code between a Windows Phone application and a Windows Store application with hopes of adding Android later.
There appear to be two separate problems in our way.
- The Multilingual App Toolkit is not available within the PCL project
- Windows Store and Windows Phone utilize different extensions for the Resource files.
Localized resources should be maintained in the PCL, but how?
The Phone project uses .resx, as does the PCL, so a Linked file structure might work.
The PCL needs the .resx files within its file structure. Create a ‘Resources’ directory within the .Core project. Within that directory create a copy of the Phone project’s Resource file.
Now that the file resides within the ‘Core’ project access its properties and set the Custom Tool to ‘PublicResXFileCodeGenerator’. This create the designer file.
Within the Phone project delete the AppResources.resx file in the Resources directory. Right click the Phone.Resources directory and ‘Add Existing -> Add as Link’ to the Core.Resources AppResources.resx file. Make certain that the Phone linked copy of AppResources.resx does not have a ‘Custom Tool’ value.
Within the Core project create a new Folder called ‘Misc’ and within that folder create a class named PortableStrings.cs. Make sure the Namespace does not include ‘.Misc’.
Within the Phone project Delete LocalStrings.cs from the project and modify App.xaml adding the portable namespace and changing LocalStrings to use the Portable reference. You will also need to eliminate ‘using references’ in Phone.MainPage.xaml.cs and App.xaml.cs. Delete the Class1.cs file.
Enable the Multilingual App Toolkit by selecting the Phone project then expose the Tools menu to ‘Enable Multilingual App Toolkit’. Then right click on the Phone project and ‘Add translation language’. This will create a <nn>.xlf file.
Select the Core project and either Refresh or Show All Files to expose all files. Because the AppResources.resx is linked the output from the Multilingual App Toolkit goes into the .Core Resources directory.
In order to include a new Language in the PCM you must manually Include the <project>.<nn>.resx file by right clicking the file and selecting ‘Include in Project’.
You must ‘Include in Project’ the ‘.resx’ files for languages you support. Below is the final structure.
That should do it, we are ready to work in multiple langauges.
Use Case Walk-Through
Now that everything is setup let’s look at how it works.
Add a new string for translation to AppResources.resx
- New string is added to AppResources.resx.
- Build the project. This populates the .xlf files but does not change the .resx files.
- Generate machine translations or edit using the Multilingual Editor setting the translation value for the newly added string.
- Build the project again.
Step by step here is what happened.
- AppResources.resx is changes (Resource string is added)
- First build: Pushes changes into the .xlf files.
- The .xlf file is changed.
- Second build: Pushes the translated values into the .resx files.
If you delete a resource string from AppResources.resx the .resx files are rebuilt on the first build. This makes sense as adding a new resource does not require an update unless a different value is provided. If you are looking at the content of the .xlf and .resx files this will help you understand.
There you have it. Add a Store project, enable the Multilingual App Toolkit and select languages. Make the appropriate change to App.xaml
NOTE: You will see a warning on the build
warning : SnapNTalk.Store -> No localizable resources were found
You can ignore this as the localization occurs in the PCL.
- Add new Resource Strings or completely delete a resource string in Applications.resx. You must build after adding or deleting a string to propagate it into the .xlf files for translation.
Manage translations using the .xlf files. Double click on a .xlf file to launch the Editor. Note the Resource ID is on the right. Make changes in the ‘Translation’ window. Save when done and remember to Rebuild after making changes.
- The AppResources.resx file is the ‘Base language’ file. Deleting a string from this file deletes the string from all of the translations as well. The .xlf files are updated as part of the build (when the XliffResxGenerator is run).
All translations are manage in .xlf files.
Do not make changes to the <nn>.resx files. The .xlf file generates the .resx file. Exposing the .xlf properties reveals there is a Custom Tool associated with the file.
If a resources string has not been translated it will not appear in the <nn>.resx file. When a translation is not available the default language value will be used so there would be no point in duplicating the untranslated value.