WSS Globalization and Localization

Localization in WSS is based on language packs that are deployed as solution packages. Language packs include resources for specific cultures that are used to localize core solution packages. We will discuss solution packages and language packs at the end of this chapter, but we first want to provide some important background information about resource files, because you will want to use text defined in resource files within site definitions, features, and solutions to enable localization for specific languages and cultures.

By moving your literal text strings out into resource files, you can create WSS business solutions for the global market that can be deployed to multiple languages and cultures. Resource files also separate your text from your code, which can make editing a solution’s literal text strings easier without the need to edit any CAML or .NET code.

For example, you could create an English solution and translate the resources into Japanese, and your solution would be deployable to Japanese markets without changing the core CAML XML files or any compiled code libraries. Site definitions and features can contain embedded resource references within their CAML, whereas Web Parts and compiled code can contain resources defined within assemblies. First, we will look at localization using resource XML files and compiled resources. We will then look at embedding the resources into language packs as we create solution packages.

Localization Through Resources

In .NET development, XML resource files can be used to embed resources into assemblies. In the case of ASP.NET, resources can be compiled at run time from XML resource files. Furthermore, the WSS runtime parses and compiles resources deployed in the installation’s RESOURCES directory for use in WSS CAML files.

One of the key benefits of using resource files is that all of the language and locale-specific elements in an application or class library DLL, such as captions and user messages, can be factored out of your application code (including CAML). To do this, you need to create a separate resource file for each spoken language you must support. The actual resource file is a text-based file containing XML with a .resx extension. The following code displays an example of the XML data found inside a resource file with a single resource named Hello.

 <?xml version="1.0" encoding="utf-8"?> <root>   <!-- schema omitted for clarity -->   <resheader name="resmimetype">     <value>text/microsoft-resx</value>   </resheader>   <resheader name="version">     <value>2.0</value>   </resheader>   <resheader name="reader">     <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>   </resheader>   <resheader name="writer">     <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>   </resheader>   <data name="Hello" xml:space="preserve">     <value>Hello</value>   </data> </root>

When working with resource files in Visual Studio 2005, you also get the benefit of a strongtyped resource manager class that is generated automatically behind the scenes. For example, we can create a resource named LitwareControlStrings inside of the LitwareWebParts assembly in the Resources folder. It will have a single resource string named “Hello” with the text “Hello”. We can also create a Japanese version, naming the resource file LitwareControlStrings.ja-JP.resx, and a US English–specific version named LitwareControlStrings.en-US.resx.

Within the Japanese resource file, you can copy and paste from the default resource, replacing the text value of the Hello string with “image from book” Paste the default resource file into the US English version, changing the “Hello” text to “Greetings”. The LitwareControlStrings resource class has a ResourceManager static instance that returns either the correct string for the current locale or the default resource from the core assembly if a language-specific resource is not available. The following is an example of the Visual Studio–generated code for the Hello resource:

 // Looks up a localized string similar to Hello. internal static string Hello {   get {     return ResourceManager.GetString("Hello", resourceCulture);   } }

When you create resources in the class library, they must be named appropriately for the target culture. When you compile the assembly, Visual Studio automatically creates a locale folder for the resources. Because we created ja-JP and en-US localized resource files, Visual Studio compiles the LitwareWebParts.resources.dll satellite assemblies in the ja-JP and en-US subfolders of the compilation target.

When you create localized resources, it is also important to include default resources that are used in situations in which the localized resource for the current culture is not available. In this example, the Web Part solution running in an Australian localized installation would use the default resources (not the US English resources) because there are no Australian localespecific resources.


The Resource Generator for Visual Studio generates internal classes for strong-named resources; however, there are several Shared Source alternatives for generating public resource classes that can be shared between assemblies.

After learning the basics of localization, you should find it easy to include resources for all of your Web Part and event handler assemblies. Now that we have an assembly resource for the Web Part assembly, let’s localize our HelloWebPart class. Instead of using the text “Hello” in the Web Part, we can read it from the resource that lets us easily localize and deploy our Web Part solution into multiple locales without changing any code. The following code block shows a new version of the HelloWebPart class that uses resources instead of the static “Hello” text.

 using System; using System.Web.UI; namespace LitwareWebParts {   public class HelloWebPart : System.Web.UI.WebControls.WebParts.WebPart {     protected override void RenderContents(HtmlTextWriter writer) {       writer.Write("{0} {1}",         Resources.LitwareControlStrings.Hello, Context.User.Identity.Name);     }   } }

Within site definitions and features, resources are not accessed through a compiled assembly when referenced from CAML, but are parsed at run time from the .resx file itself. However, you can still compile the resource if you wish to use it in any feature event receivers that are defined in the assembly. Within site definition or feature projects, place the resource in the Resources folder of the Visual Studio project. On your development machine, you can copy the Resources folder to the WSS Resources folder with a build event such as the following:

 @SET RESOURCEDIR="c:\program files\common files\microsoft shared\web server extensions\12\ RESOURCES" xcopy /e /y RESOURCES\* %RESOURCEDIR%

We will later package the resources into the solution package for deployment. To create localized resources for your custom WSS components, use Visual Studio to add a new Resources directory to your project. These resources will be copied to the RESOURCES directory and interpreted by the WSS runtime as it parses the CAML file’s XML content. Note that the resources won’t be accessible from a compiled assembly when created and deployed in this fashion.

Now that we’ve learned the basics of resources, in the Resources directory of the Litware Marketplace site definition, create a resources file named LitwareMarketplace.resx. We’ll also create a Japanese version named LitwareMarketplace.ja-JP.resx. (Don’t worry if you don’t know Japanese, you can include placeholders for the interpreters to translate. We used AltaVista BabelFish to translate while writing this book.) This allows us to create a basic localized site definition for Litware that can be translated easily into other languages. Figure 9-3 displays the LitwareMarketplace.resx file containing the core string definitions CustomerListTitle, DefaultAnnoucementBody, DefaultAnnoucementTitle, ServerEmailFooter, SiteTitle, and VendorListTitle.

image from book
Figure 9-3: Visual Studio provides a resource file editor for working with resources, such as literal text strings.

Resources in SharePoint XML Files

After creating the .resx resource file, we can reference these resources in any CAML-schema XML files including site definition files, feature definitions, and list schemas. (The only CAML files you cannot localize are the prelocalized WEBTEMP files.) For example, instead of including a nonlocalized default announcement, we could create the following announcement in the site definition that can be created with the locale of the operating system upon site creation.

 <List FeatureId=""     Type="104" Title="$Resources:core,announceList;"     Url="$Resources:core,lists_Folder;/$Resources:core,announce_Folder;">   <Data>     <Rows>       <Row>         <Field Name="Title">$Resources:Litware,DefaultAnnoucementTitle;</Field>         <Field Name="Body">            $Resources:Litware,DefaultAnnoucementBody;</Field>         <Field Name="Expires">&lt;ows:TodayISO/&gt;</Field>       </Row>     </Rows>   </Data> </List>

Note that the resource format within CAML is $Resources:ResourceFile,ResourceName;, where ResourceFile is the name of the file and ResourceName is the name of the string within the file. The WSS runtime replaces this as it parses the CAML. Note that you can access the localized site definition (which is cached for the Internet Information Services [IIS] application lifetime) through the site-relative URL _vti_bin/owssvr.dll?Cmd=GetProjSchema.


For more background information on localization support in the .NET Framework and Visual Studio, read the following two MSDN columns written by Ted Pattison:



Inside Microsoft Windows Sharepoint Services Version 3
Inside Microsoft Windows Sharepoint Services Version 3
ISBN: 735623201
Year: 2007
Pages: 92 © 2008-2017.
If you may any questions please contact us: