CHAPTER 12

image

Supporting Multiple Languages

In today’s global economy, many businesses trade, operate, and carry out business across international boundaries. Such businesses can benefit greatly from applications that can support multiple languages. In this chapter, I’ll show you how to do the following:

  • design applications in a way that can simplify the process of localization
  • localize HTML and desktop applications
  • localize server-side messages and objects

Localization is the process that adapts an application so as to support a range of languages and cultures. To demonstrate this process, this chapter will show you how to translate the Help Desk application into a language other than English.

Introduction

In many cases, applications support just a single language. The chances of your needing to localize an application may seem remote. However, it’s still worth considering that one day you might need to localize your application. By considering localization issues at an early stage, you can more easily carry out this task when the need arises.

At the most basic level, you can localize an application to support a different culture. An example of this might be the adaptation of a US application to support UK customers. The main bulk of this work would involve changing the spelling of words and reformatting date values to adhere to UK standards. Therefore, the process of localization doesn’t need to be as radical as supporting an entirely foreign language.

The process of localizing an application involves abstracting the words and descriptions in your application into resource files. By using localization techniques, you can easily modify the words and labels that appear in your application. The localization technique isn’t limited to just foreign language support. For example, if you create an application that’s used by two different customers, you can modify the words and expressions that appear in the application by changing just the content of the resource files. The core code base for your application can remain the same for both customers.

The need to support a foreign language might arise when companies merge, develop new trading partners, or are sold. These types of events can happen frequently in corporate environments.

Having considered some of the reasons why you might need to localize an application, the good news is that there are simple steps you can follow to do so. If you’ve localized .NET applications before, the tasks involved will be familiar to you.

Let’s review the high-level steps. First, you need to develop your application and screens in a way that’s easy to localize. Second, you need to provide foreign language translations for the English words in both your client and server projects. The remainder of this chapter will describe these two processes in further detail.

Supported Languages

LightSwitch includes built-in dialogs and warning messages that are familiar to you. These are messages like “Cannot save – another user has modified the record” (Figure 12-1). LightSwitch provides translations for these system messages in 42 culture specific languages. You can see the list of supported languages by looking at the Default Language dialog in the General Properties of your application. The languages that LightSwitch supports include traditional Latin languages, in addition to right-to-left languages such as Chinese, Japanese, and Arabic.

9781484207673_Fig12-01.jpg

Figure 12-1. LightSwitch can display localized system messages

Ideally, the target language of your application should be one of these 42 languages because this would allow you to build an application with matching UI and system message languages.

Preparing an Application for Localization

There are various issues to consider when you build an application that you might want to localize. By keeping these considerations in mind, your job will be much simpler when that need arises.

The first consideration is label length. When you translate words from one language to another, the length of the translated text will be different. For example, English words that you translate into German will often take up more space. Therefore, you should allow additional space to account for differences in word length when you design screens, and you should avoid setting static widths on labels. The best way to design a screen is to top-align labels (Figure 12-2). This provides space for the label text to grow or shrink. An extra benefit of top alignment is that it better supports the conversion of an English screen to a right-to-left language.

9781484207673_Fig12-02.jpg

Figure 12-2. You can more easily localize screens with top-aligned labels

One other thing to avoid is hard-coded text in images. It takes more work to recreate images each time you localize an application into a different language than it does to localize plain text.

Items that differ between cultures include address formats, date formats, and weights and measures. For example, there are subtle differences in street addresses, zip codes, and phone numbers between different countries. On a screen such as an address registration form, you can fix this issue by creating separate screens for each culture and opening the most suitable screen based on the locale of the user.

Date formats differ between regions. With .NET, you can use built-in functions to format dates in long and short formats based on the location of the user. It’s good practice to use these features rather than hard code the date formats in your application.

Different languages have different rules on pluralization. For certain languages, pluralization rules can be quite complicated. In English, you can pluralize a noun by adding (s) or (ies) to the end of a word. But in Polish, you would pluralize a noun by adding (i,y) to words that end in a vowel and (-e,y,i) to words that end in a consonant. This specific rule applies to two or more objects. For five or more objects, the rule is more complex. In this case, you need to remove the vowel from words that end with a vowel. To avoid writing complex pluralization code, you can simplify the translation task by phrasing messages in such a way as to avoid pluralization. For example, rather than display the confirmation message “You are about to delete 10 records. Do you wish to continue?”, you can use the phrase “Please confirm the delete operation (record count: 10).” The latter phrase saves you from needing to write code to determine the singular or plural form of the word record.

Finally, don’t be tempted to localize everything. For example, make sure not to localize the currency symbol of a money field if the underlying purpose of the field is to store money values in a specific currency. Also, it’s often a good idea to avoid translating technical error messages, especially if the people who support your application are not fluent in the target language.

Localizing Server Objects

To add support for multiple languages, you need to modify both the server and the client parts of your application. I’ll begin by describing the server tasks that are required in order to localize an application. A fundamental step is to localize the display names for the properties in your tables. Once you complete this task, every property label on all screens in both desktop and HTML client applications will display the localized value. Therefore, the benefit of this technique is that you can make quick progress by making a change in only a single place (the table).

The steps to localize table property display names are as follows. First, you need to create two or more resource files in the root folder of your Server project. The purpose of these resource files is to store the translated values. The first resource file is called service.resx. This file contains the default resource values. If, for example, a user attempts to view a French version of your web application, and your application doesn’t include French resources, your application would use the values that are stored in the service.resx file. The next step is to create localized resource files for the languages that you want to support. The names of these files should be in the format service.en-GB.resx. In this example, en-GB signifies a file that contains an English-language resource with a British culture. You can create culture-agnostic resource files by omitting the culture code. In this example, you could create a generic English resource file by naming your file service.en.resx. Supposing that your application includes a British English resource file and a generic English resource file, your application would use the British file for British users and fall back to the generic file for all other English users. These other users could include US, Australian, Canadian, and South African users.

The second stage is to create client-side resource files in your desktop or HTML client projects. These resource files enable the client to localize UI elements such as screen titles and button captions.

To localize a table property display name, you would open the table designer, select the Display Name setting for the property that you want to localize, and replace the English text with the syntax $(ResourceKey). In this instance, ResourceKey refers to a key value in the resource file. These key values can contain only letters and numbers, and not spaces. The actual resource value can contain any valid character. Once you carry out the substitutions on all the fields you want to localize, you can run your application. I’ll show you later how to change your language settings in order to test your application.

Translating Table Field Names

To demonstrate how to localize a table, this section will show you how to translate the display names in the Engineer table from English to Spanish.

The first step is to create the two service resource files. To do this, right-click your Server project and select the “Add image New Item” option. When the Add New Item dialog appears, click the General container, add a new resource file, and name it service.resx. Now, add another resource file and name it service.es-ES.resx. The es-ES part of the filename indicates that this is a resource file for the Spanish language and Spanish culture. Edit these two resource files and enter the key-value pairs as shown in Figure 12-3.

9781484207673_Fig12-03.jpg

Figure 12-3. Contents of the Default and Spanish service resource files

For HTML client applications, you must create a client resource file. To do this, create a new folder called Resources in the Content folder of your HTML client project. Next, select the right-click “Add image New Item” menu item and create a new file called client.lang-es-ES.resjson. Note that the Add New Item dialog for JavaScript projects excludes the option to add resjson files. Therefore, choose the “Text File” option instead. Once you have created this file, type the characters {} into the file. This is the syntax that defines an empty JSON object. There’s no need to provide any translation data at this stage. The critical step is to create a folder called Resources with at least one valid resjson file within it. If you fail to carry out this step, the HTML client will always show the default values that you define in the services.resx file and will never show the values that you define in the localized resx files.

For desktop applications, you need to create at least two resource files in the root of your client project. Name the default file Client.resx and Spanish resource file Client.es-ES.resx.

At this point, you can localize the table property display names. Open the Engineer table, select the first name property, open the properties sheet, and set the value of the display name property to $(Firstname), as shown in Figure 12-4. In this syntax, Firstname refers to the key value in the resource file. Repeat this process for the remaining properties in the table.

9781484207673_Fig12-04.jpg

Figure 12-4. Resourcing the Display Name setting of the Firstname property of a table

A useful tip is that you can use this substitution technique for any of the property-sheet settings in the table designer. As Figure 12-5 illustrates, you can even use this technique to localize the display name values that you define in choice lists.

9781484207673_Fig12-05.jpg

Figure 12-5. Resourcing choice list items

At this point, the localization task of the Engineer table is complete, and you can now run your application.

Testing a Localized Application

To test your HTML client application, change the language setting of your browser and restart your application. In Internet Explorer, you can do this by clicking the Tools menu (or cog icon), selecting Internet Options, and clicking the Languages button in the General tab. For Windows 8 and above, you configure the language settings of IE through Windows Control Panel. The Languages button in the Internet Options dialog takes you to the correct place in Control Panel.

To test a desktop application, use Windows Control Panel to change the language settings of your PC. When you restart your application, the screens will appear in the target language.

Figure 12-6 shows a localized HTML client version of the application. As this screenshot shows, the table field names are now localized. However, some remaining parts of the application still require localization. This includes the screen title, the screen entries that appear in the navigation menu, and the caption that appears beneath the Add and Search buttons. I’ll show you how to localize these parts of your application later in this chapter.

9781484207673_Fig12-06.jpg

Figure 12-6. Example of a localized application in Spanish

Translating .NET Server Messages

An important server task is to localize any messages that you create in .NET code. To give an example, let’s review how to translate one of the validation messages from earlier in this book. This message shows a warning when a user attempts to set the closed date of an issue to a value that’s earlier than the create date.

The first step is to append the validation warning to the default service and Spanish resource files (Figure 12-7).

9781484207673_Fig12-07.jpg

Figure 12-7. Contents of the default and Spanish service resource files

Once you add your localized error message, you can modify your validation logic to use the localized value, rather than the hard-coded value. The code that you need to use will depend on your client type.

Desktop Application Code

In the case of a desktop application, select the ClosedDateTime property in the table designer, click the Custom Validation link in the properties sheet, and add the code that’s shown in Listing 12-1. Make sure to add the necessary references to the top of your code file.

The code in this listing retrieves the ValidateClosedDate value from the server resource file for the target language. The VB.NET syntax uses the methods in the My.Resources namespace to retrieve the resource value. If Visual Studio fails to find this namespace, open the properties sheet for both resource files and check that the Custom Tool and Custom Tool Namespace settings are set to ResXFileCodeGenerator and My.Resources respectively (Figure 12-8). Visual Studio can lose these settings if you copy and paste, or rename your RESX files.

9781484207673_Fig12-08.jpg

Figure 12-8. Custom Tool and Custom Tool Namespace settings

For desktop applications, LightSwitch links the service resource files to the root of your client project. In this case, you will also need to set the Custom Tool and Custom Tool Namespace values for the RESX files that appear in your desktop client project. The fact that LightSwitch links the server resource files to your client project allows the client-side Silverlight code to access the resources that you define in your server resource files.

The code in the C# listing uses reflection to retrieve the resource value. The reason I use reflection is because this technique works for both desktop and HTML client applications. The VB.NET listing can avoid reflection because the step that’s shown in Figure 12-8 exposes the service resources in the desktop client project via the My.Resources.Service accessor. It takes more effort to carry out the equivalent step in C# and, therefore, using reflection is the simpler option.

At this point, you can run your application. If you switch your language setting to Spanish and attempt to set the closed date to a value that’s earlier than the create date, the application will display the localized error message as shown in Figure 12-9.

9781484207673_Fig12-09.jpg

Figure 12-9. A localized version of the validation error

Image Tip  As the code in this section shows, it’s a good idea to add a comment that shows the validation message in English. This can make your code more readable when you need to debug your application.

HTML Client Code

If you apply the validation code from Listing 12-1 to an HTML client application, the validation message won’t appear in the correct language.

As Figure 12-10 shows, if you set your browser to Spanish, the validation warning appears incorrectly in English while the rest of screen appears correctly in Spanish. The reason why the code works in desktop applications is because Silverlight executes the .NET code on the client. Therefore, the code can correctly determine the client language. In the case of a HTML client application, LightSwitch executes the validation code on the server because the HTML/JavaScript client cannot execute .NET code. Therefore, the validation code selects resources that match the language of the server rather than the language of the client. Therefore, you need to write some additional code to enable the validation code to work correctly in HTML client applications.

9781484207673_Fig12-10.jpg

Figure 12-10. The validation code doesn’t retrieve the correct resource in HTML client applications

To localize the validation warnings for HTML client applications, open a table in the designer, select the SaveChanges_Executing method from the Write Code button, and add the code that’s shown in Listing 12-2.

This code relies on methods in the system.web namespace to determine the language of the client. The UserLanguages collection returns an array of the languages the user has selected in the Internet Options section of their browser image. The next line of code changes the UI culture and the culture of the thread that retrieves the resource. This ensures that the code retrieves the resource value in the language that matches the client. If you now run your application, the validation warnings will appear in the correct language.

Because the server executes the code in this listing at the start of the Save pipeline process, all validation rules that refer to resources will apply the correct language. You don’t need to modify individual validation rules to apply this change.

In the previous section, I demonstrated C# code that uses reflection to retrieve resource values. If your solution contains only an HTML client, you can avoid the use of reflection by using the shortcut accessors in the service namespace. One benefit of this technique is that the code editor provides IntelliSense suggestions for all the resource values that are available. For example, you can use the C# syntax Service.Service.ValidateClosedDate to retrieve the specific validation message that I showed you in the previous section.

Localizing HTML Client Resources

After you have localized your Server project, the next step is to localize the messages and UI elements in your client project. These resources include screen titles, hard-coded pieces of screen text, menu-navigation items, and JavaScript alerts. LightSwitch utilizes client resource files to implement client-side localization, and I’ll now explain how to carry out this localization task.

Localizing Screen Titles and Menu Items

Screen and menu titles are prominent parts of an application that require localization. In this section, I’ll demonstrate how to localize the screen title of the Browse Engineer screen. The first step is to append the localized values to a set of client resource files. Like the server localization task, the client project requires a default resource file. This file contains the resource values that LightSwitch uses when a user attempts to view your application in a language that you do not support. To add a default resource file, create a new file called client.lang-en.resjson in your ContentResources folder. The language code of your default file must match the language of your web server. Unlike the server project, you can’t define a default resource file by simply naming a file client.resjson. The correct way to define a default resource file is to name your file with a language and/or culture that matches the language and culture of your server. Because this example assumes that your target server is set to English, the name of the default resource file is named client.lang-en.resjson.

After you create your default resource file, make sure to create a localized resource file in your ContentResources folder. In our example, the name of the Spanish resource file would be client.lang-es-ES.resjson. Now, populate both files with the contents that are shown in Figure 12-11.

9781484207673_Fig12-11.jpg

Figure 12-11. Add the translated values to your client resource files

To configure a screen to use the localized screen title value, replace the Display Name setting of your screen with code that references the localized version in your client resource file. Taking the example of the Browse Engineer screen, you would replace the Display Name setting with the value $(BrowseEngineers), as shown in Figure 12-12.

9781484207673_Fig12-12.jpg

Figure 12-12. Localizing the screen title

You can use this same approach to localize the Display Name setting of the Add and Search buttons on this screen. When you now run your application, LightSwitch shows the localized screen title (Figure 12-13). Because LightSwitch uses the screen display names to build the navigation menu, this process also localizes the navigation menu and window title.

9781484207673_Fig12-13.jpg

Figure 12-13. Localized screen title, menu, and window titles at runtime

Image Caution  When you set a Display Name value to $(MyKeyValue), make sure there are no inadvertent trailing spaces after the end bracket. It’s easy to append trailing spaces by mistake when you copy and paste words between files. If there are trailing spaces, LightSwitch shows the key rather than the localized value, and you might struggle for a long time to find out why.

Localizing JavaScript Messages

A typical application will include text values that are defined through JavaScript code. This might include screen text values or validation warnings. To demonstrate how to localize such pieces of text, let’s review how to localize the property value that shows the information message from Chapter 8. Like the previous example, the first step is to append localized values to your client resource files. This example relies on a key value called ValidationRequiredField that defines the string "(*) indicates required field".

This example requires you to add a local string property called screenHeading to your Add/Edit Issue screen and to add a text control that binds to this property. Once you do this, select the created method from the Write Code button and add the code that’s shown in Listing 12-3.

As this code sample illustrates, you can replace any hard-coded string value with a call to the WinJS.Resources.getString method. This method returns the localized value based on the resource identifier that you supply to the method. In this case, the resource identifier is called ValidationRequiredField (as shown in Figure 12-11).

Localizing Dates and Numbers

When you display date and numeric values with the default screen controls, LightSwitch automatically formats the data for the target locale. Therefore, you don’t need to carry out any additional work to format dates and numbers in the correct format. Figure 12-14 illustrates a screen in a Spanish browser that includes the date picker and text controls control. Notice how LightSwitch automatically configures the date picker to use the target locale.

9781484207673_Fig12-14.jpg

Figure 12-14. Automatically localized date and number values

If you have code that applies custom formats using the momentjs or numeraljs libraries, you can store the localized formats in your resource files and use the JavaScript code from the previous section to retrieve the required format.

Localizing Desktop Apps

In this section, I’ll show you how to localize the client section of a desktop application. To begin, I’ll show you how to localize the items that you define declaratively in the designer, and, afterward, I’ll show you how to localize .NET code.

Localizing Screen Titles and Menu Items

You can localize the screen title and other settings that you define declaratively in the screen designer through a technique that’s very similar to the technique that you would use for an HTML client screen. The first step is to append the translated values to your client resource files, as shown in Figure 12-15. You should add a file called Client.resx to the root of your desktop client project. This file defines your default resource file. For our Spanish example, you would also need to create a file named Client.es-ES.resx and add it to the root of your desktop client project.

9781484207673_Fig12-15.jpg

Figure 12-15. Add the translated values to your client resource files

The second step is to replace the Display Name setting of your screen with code that retrieves the localized version from the client resource file. Taking the example of an Editable Grid screen of engineer records, you would replace the Display Name value with the value $(EditableEngineerGrid), as shown in Figure 12-16.

9781484207673_Fig12-16.jpg

Figure 12-16. Localizing the screen and menu group display names

LightSwitch uses the screen Display Name values to build the application navigation menu. Therefore, this process also localizes the navigation menu items. In desktop applications, the menu items are organized into navigation groups. You can use this same localization approach to set the navigation group display name (also shown in Figure 12-16).

When you now run your application, LightSwitch shows the localized menu and screen title values (Figure 12-17).

9781484207673_Fig12-17.jpg

Figure 12-17. Localized screen title, menu, and window titles at runtime

Localizing Silverlight .NET Code

Your screens might contain hard-coded strings in .NET code that require localization. To demonstrate how to localize strings that you define in .NET code, let’s localize the confirmation message code sample from Chapter 9. Just like in previous examples, the first step is to append the translated values to your client resource files, as shown in Figure 12-18. This screenshot includes translated values for both the confirmation message title and message itself.

9781484207673_Fig12-18.jpg

Figure 12-18. Add the translated values to your client resource files

Next, you replace the hard-coded text with code that retrieves the translated text from the resource file, as shown in Listing 12-4. This code looks similar to the earlier example where you resourced .NET server code. The main difference is that this code retrieves the localized values from the client resource file, rather than the server resource file. Unlike the earlier example, the C# code retrieves the localized values via the client accessor. The earlier example used reflection to enable the code to run on both the server and client tiers. Because this code only runs on the client, you can simplify the code by avoiding the use of reflection.

You can now run your screen; Figure 12-19 shows the appearance of the localized message box at runtime.

9781484207673_Fig12-19.jpg

Figure 12-19. Localized message-box text at runtime

Summary

In this chapter, I showed you how to build applications that can support multiple languages. I described screen-design techniques that you can use to simplify localization, and I explained the steps that you need to carry out on the server and client to fully localize an application.

There are certain design practices that can help simplify the development of a localized application. When you design a screen, you should try to top-align labels above textboxes, and you should try not to apply static widths or heights to controls. When you translate a word to a foreign language, the length will often be different. If you follow this practice, you’ll face fewer problems with the alignment and sizing of controls. You can also reduce the amount of work you need to carry out by phrasing messages in a way that avoids pluralization. This saves you from having to write code to count the number of objects before choosing the correct spelling of the noun.

You can localize a large part of your application by localizing the table property display names. Once you do this, any labels on screens that are based on the table will show the localized values. Another task you need to carry out in your Server project is to localize any messages that you generate in code, such as validation warnings.

The technique with which to localize an application is to create resource files. Resource files contain key and name pair values. You create separate resource files for each language that you want to support. Within your application, you would replace each instance of an English phrase with code that looks up the translated version from the resource file.

To localize table property display names and other server elements, create a file called service.resx in the root of your server project. Next, create resx files for each language you want to support in your application and name the file with the locale identifier after the word service. For example, you would name a Spanish resource file service.es-ES.resx. The next task is to populate the resource files with translated values that are keyed with an identifier. If you key the word Firstname with the identifier Firstname in the resource file, you would localize the display name of the table property by replacing the Display Name setting with the following syntax: $(Firstname).

To complete the localization task, you need to localize resources that are specific to the front-end client. This includes screen names, button captions, and menu items. To localize UI elements, you need to create client resource files that contain key-name values. For an HTML client application, you would create a ContentResource folder and create a file inside this folder called client.lang-en.resjson. The name of the Spanish resource file would be client.lang-es-ES.resjson. In the case of a desktop application, you would add the resource files to the root of your desktop project and name the default and Spanish files client.resx and client.es-ES.resx respectively. To replace a hard-coded value in the client (for example, a button caption), you would replace the Display Name setting with the code $(KeyValue), where KeyValue identifies the key value in the resource file.

To retrieve localized values in server-side C# code, you would write code that uses a Resource Manager object. In VB.NET code, you can shortcut this by using the strongly typed resource accessors that you can find in the My.Resources namespace. In JavaScript, you would write code that calls the WinJS.Resources.getString method.

To run an HTML client application in a different language, simply change the language setting of your browser. To run a desktop application in a different language, you would need to change your language setting through Windows Control Panel.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset