This blog post was authored by Dan Zucker, a program manager on the Windows Phone team.
- Adam
As part 2 of this two-part series, this post focuses on the great new Multilingual App Toolkit (MAT) v1.2 offered by the Windows International team. This Windows 8 tool now supports Windows Phone 8 and Windows Phone 7.5 development. Part 1 focused on providing an understanding of the standard pattern for localizing a Windows Phone 8 XAML app.
TOP TEN MAT FEATURES
Here’s my top-10 list of what makes Windows International team’s MAT v1.2 so great:
- Pseudolocalization support
- Helps avoid localization pain by testing your UI localizability early in the process
- Saves repetitive labor and bug fixing for tasks that globally impact localized strings
- Integrates status communication between dev and translator
- Makes it easy to create, import, and export translation files in industry-standard format
- Tools to create and localize a Windows Phone app don’t cost anything:free download!
- Lowers the cost and technical skill bar for language specialists
- No need to switch back and forth between resource files
- Give behavior and intended meaning notes right in the tool
- Add translation languages item right from the Project context menu
- Global resource description comments PLUS local, per resource comments
GETTING STARTED
To start using the Multilingual App Toolkit for your Windows Phone project, download and install the Visual Studio 2012 extension from MSDN here. Using this tool begins when you have a working single language app that is localization-ready.
Localization-ready means:
- Hard-coded XAML and code-behind strings that are to be localized have been placed in a resource file string table and given a unique key name
- Each hard-coded value is replaced by a binding clause in XAML or a resource reference in code using the key name for its related string resource. This is described in more detail in Part 1.
For my example in this blog, I’ll continue using a localization-ready version of my Humanitarian Reader app from Part 1. With MAT installed, I selected the Project and then Enable Multilingual App Toolkit inthe Tools menu:
NOTE: Localized resources are per project, not solution-wide, so Visual Studio’s focus must be within the project for the Enable Multilingual App Toolkit option to be available in the Tools menu. If you have the Solution selected in Solution Explorer, that option is dimmed. |
Enabling MAT has several effects on the project; the most noticeable is the addition of a pair of new files, one with a new type and a mysterious name: AppResources.qps-ploc.xlf. Here it is in the Solution Explorer:
The .xlf extension is associated with the localization industry standard XLIFF file format, which MAT generates for you. Do not worry if you use your .resx files for image localization or non-localization purposes. You’ll see that when MAT adds an .xlf filefor a locale, it creates an associated .resx file and tucks it safely in the project hierarchy underneath its .xlf file. MAT manages only the string table, leaving other aspects of .resx files alone. You can even tell it to leave selected strings alone by setting the Translatable workflow flag for those resources to No.
PSEUDOLOCALIZATION
The locale specified for the resource file, qps-ploc, is associated with a pseudolocalized “translation.” Pseudolocalization is a common localization best practice: original characters are replaced by look-alikes from a variety of other language’s scripts, and a percentage of string length is added to each resource. All that is surrounded by brackets to visually emphasize what is pseudolocalized (MAT even adds a unique ID number to each resource string for easy reference between the UI and the resource file). Text is still readable but is now formatted in a way that helps ensure two things:
- The UI design is localizable. In other words, it accounts for things like the greater amount of space translations into other languages sometimes take and/or using different character sets than the original language.
- Everything you want localized in your app is drawing its value from resources rather than a hard-coded string.
MAT brings pseudoloc, as it is commonly called, to Windows Phone. Adding a few lines of code to your app’s initialization code allows you to do pseudoloc testing as part of your final UI design refinements. Later on, the same code also makes your international testing easier.
Here’s how to turn on pseudoloc by forcing the CurrentUICulture to the locale “qps-ploc”:
- Right-click AppResources.qps-ploc.xlf and select Generate pseudo translations.
You can see the effect of this action by double-clicking the .xlf file to open the Multilingual Editor.
Note that MAT also prepends an ID number to each string to make it easy to relate what you see in your UI to each resource. - Save and Rebuild Solution. Visual Studio will ask whether you want to reload a file that has been modified. Click Yes.
- In App.xaml.cs, add the following two using statements: C#
- using System.Threading;
- using System.Globalization;
- In the App class, add a static string variable to contain the forced locale: C#
- publicpartialclassApp : Application
- {
- // Locale to force CurrentCulture to in InitializeLanguage().
- // Use "qps-PLOC" to deploy pseudolocalized strings.
- // Use "" to let user Phone Language selection determine locale.
- publicstaticString appForceCulture = "qps-PLOC";
- // ...
- In the InitializeLanguage() function, use appForceCulture to set the CurrentUICulture of the app: C#
- // ...
- privatevoid InitializeLanguage()
- {
- try
- {
- // Force CurrentUICulture to locale defined by appForceCulture.
- // An empty string allows the user's Phone Language setting to
- // determine the locale.
- if (Debugger.IsAttached &&
- String.IsNullOrWhiteSpace(appForceCulture) == false)
- {
- Thread.CurrentThread.CurrentCulture =
- new CultureInfo(appForceCulture);
- Thread.CurrentThread.CurrentUICulture =
- new CultureInfo(appForceCulture);
- }
- // ...
- Save and Rebuild Solution, then deploy to your emulator.
UI Adjustments
When I took those steps, the results for the Humanitarian Reader app showed several localizability issues that needed attention:
You can see in the illustration that in three cases the longer pseudo translations where truncated by running under another element or by running out of their control. Also, the missing square brackets and pseudo characters showed me that the “go to news” label was not bound to a resource as I had intended.
Deciding to localize the forgotten item was easy. Determining what to do about the truncation issues took some judgment. MAT’s pseudo ID numbers are a blessing for a complex, large, or repetitive UI, but for short strings they probably exaggerate the string length impact that even a long language like German is likely to add. After I shortened the pseudo translation (by deleting the ID number in the Multilingual Editor), I decided that the possibility that real translations would cause truncations was a low risk.
With my pseudolocalization done, I returned the app to normal behavior (CurrentCulture determined by user’s Phone Language selection) by modifying the value of appForceCulture in App.xaml.cs to an empty string:
- publicstaticString appForceCulture = "";
ADDING LANGUAGES
Now that I had confidence that my UI could handle a wide variety of scripts and languages, I was ready to add the languages I wanted. MAT supplies a Project context menu item called Add translation language that achieves the same function as adding a Supported Culture via the Project’s Application Properties tab.
Note that adding a Translation language via MAT causes a new SupportedCulture to be added. Just like adding a Supported culture, it also causes the addition of a Supported Language in the Project’s WPAppManifest.xml. If a language is present in the manifest’s language list, the app’s Store details will indicate its support for that language.
When you add or delete either a Translation Language or Supported Culture, the project metadata in .csproj file is updated automatically.
.XLF and .RESX linkage
With Arabic added, I saw that an AppResources.ar.xlf file and its dependent AppResources.ar.resx files had been newly created. I noticed at this point that AppResources.ar.xlf file (viewed in the Multilingual Editor) contained a copy of the primary (neutral) language strings from AppResources.resx and that AppResources.ar.resx contained only the two default language parameter strings initialized by Visual Studio (see Part 1). This is part of the way that the Toolkit manages the differences between translated and untranslated resources.
To machine translate the resources to Arabic, I right-clicked the .xlf file and selected Generate machine translations.
I applied the translations, rebuilt the project, and approved the prompt to reload the AppResources.ar.resx file. When the resx file was reloaded, I could see the translated resources from my AppResources.ar.xlf file. (Coincidentally, if you have an .xlf file open in the Multilingual Editor and you change the file outside that tool in some way, in most cases you will see a prompt to accept an update to the content in the editor.)
It is important to note that changes to the string resources should be made in the .xlf file, NOT in the .resx file. Any change made in a .resx file in a MAT-enabled project is overwritten by changes in the .xlf file. |
Machine translation and international testing
Next, I added the rest of the languages I wanted and machine translated them. Probably you’ve already gleaned that when you click Generate machine translations,MATinteracts with the Microsoft Translator service.
To repeat from Part 1: You still need human translation for most quality requirements. However, any machine translation typically reduces the time for human translation—and the better the quality, the less work for the translator and less cost for you. It also means that while you wait for human translation, you have a high quality indication of what the app looks like in different languages. This is the reason that any machine-translated string has a state of ‘Needs review’.
With all my strings in place and machine translated, it was time to do an international test pass. Although I couldn’t ensure that the translations were correct, there were many potential errors I could catch and fix. Specifically, I wanted to verify that all my translated strings showed up where I expected, in the script I expected, under the circumstances I expected. For my app design that meant three tests:
- BASIC LOC VALIDATION: Does the app language change to the expected language for all UI elements? Does the script flow in the expected direction?
Here I used the same technique as the one described for pseudo localization earlier: I changed the value of appForceCulture to match the language I wanted to test, and then rebuilt and redeployed. For Arabic:C#- // ...
- // Locale to force CurrentCulture to in InitializeLanguage().
- // Use "qps-PLOC" to deploy pseudolocalized strings.
- // Use "" to let user Phone Language selection determine locale.
- publicstaticString appForceCulture = "ar";
- // ...
- FOLLOW PHONE LANGUAGE ON LAUNCH: Does the app language across the UI follow the user’s selection of phone language at launch time?
Testing per launch language meant that I needed to deploy the app, test, and then use Settings>Language + region>Phone language to cycle through the relevant languages. A reboot is required after changing the phone language. - ON-THE-FLY LOC: Does the app language change across the UI at run time when the user selects a new language from the app bar menu?
For this test, I simply exercised the menu I had coded in the app bar and examined the UI for each menu item. For completeness, I also checked the matrix of each menu item as I cycled through launching into each phone language.
Working with a translator
Few people would think that it's a bad idea to make their app available to millions of more users or to take an inexpensive step with excellent chances of doubling installations and revenue. Yet when I ask software authors why they don’t localize, they often say: “How do I find or work with a translator?” I and others at Microsoft are working on a great answer to this question, but there is already a pretty good one: Do a web search. On Bing you will find a big variety of offerings from “$.05 a word!” to membership organizations with certification programs and free quotes for a range of quality and cost like ProZ * (an example, not an endorsement!). You’re smart, you can do it!
Things a translator likely wants to know in order to give a quote:
- How many words are in your app?
- How many pages are in your app?
- Is there any special domain knowledge that is required to know the right meaning?
MAT makes working with a translator easier in several ways. First, the integration of .xlf format files, which are supported by all major localization tools, means that whoever I work with can use the tools they are familiar with. The Multilingual Editor itself is a free standalone .xlf tool that is super useful for the very common ‘friends and family’ scenario (where someone, perhaps nontechnical, in my social network is fluent in a language I need).
Embedded comments and workflow status are another part of the charm of the .xlf format, and MAT integrates these beautifully. Comments are key to providing the context of a given UI element. For a resource like “Page Title,” you might write something like “This is the title of the app page, not the ‘Title Page’ as one would find in a book.” To add to the context, my comments also refer to screen captures I made of the app in order to illustrate app behavior or look and feel.
Previously, one had to copy and paste any comment edits to the resource file of each language. MAT makes this a one-stop operation: To add a comment, I edited the comments field of a resource in AppResources.resx. When I rebuild, the comments show up for each resource across all language files. Additional comments can be added using the Multilingual Editor, so the translator can communicate resource-specific notes or questions.
On the other hand, both the dev and translator can add or delete comments that are local to each language resource file. Q and A threads, work notes, or whatever is relevant to just the language of the resource can be captured and reviewed right in the tool.
Workflow features show me the ID of each resource in my code and allow to me to protect it from translation if needed. They allow my translator and me to mark the progress of a given resource and see whether or not it has been machine translated.
With MAT, transferring a resource file to or from a translator could hardly be easier: right-click an .xlf file in Solution Explorer and select Send for translation or Import translation.
When sending translation requests by email, a link to the setup file for the toolkit is provided. The setup process automatically limits the installation to only the Multilingual Editor if Visual Studio is not installed.
Happy localizing!
* The offerings and resources presented may be relevant to developers. However, these pages are for informational purposes only and Microsoft is providing this information "as is" with no warranties. Each contribution is licensed to you under an agreement by its provider, not Microsoft. It is your responsibility to evaluate if these resources are suitable for your usage.