Tuesday, June 2, 2009

Localization of SharePoint Project

By Hristo Yankov

UPDATE: For detailed step by step tutorial, check those posts:
SharePoint localization step-by-step part 1
SharePoint localization step-by-step part 2

Problem: The users require that your custom SharePoint ASP.NET site is available in more than one language. For instance - English and Hungarian.

Solution: ASP.NET localization. Technique is discussed in this article, step by step.

It is recommended that you leave localization to the end of the development, when page content is not going to change (too often). Otherwise, you will find yourself constantly syncing new web content with the resource files.

1. Create resource files.
Create a folder in your project called, for example, 'Resources' and add a new .resx file (right click -> Add -> New Item -> General -> Resource file) in it. DON'T give it a generic name like 'Resources.resx'. Instead, name it similarly to your project - e.g. WarehouseManagement.resx. This will be the resource file for your default language (let's assume it's English).

2. Extract site content in the resource file
This is a boring, but relatively easy task to do. You need to extract page contents such as literals, control texts, headers, titles and etc. into the resource file. The actual text is being replaced with Resource reference, using:
<%$ Resources:[Resource File Name Without Extension],

[Resource Name]%>

For example, if you have:
<cc1:sptoolbarbutton id="btnSearch" runat="server" text="Search" 


You extract the 'Search' button text into the resource file, and let's assume you give it a key 'btn_Search'. Then you edit the button code so that you end up with:
<cc1:sptoolbarbutton id="btnSearchProperty" runat="server"

text="<%$Resources:WarehouseManagement,btn_Search %>"

Another example:
<asp:content id="PageTitle" contentplaceholderid="PlaceHolderPageTitle" runat="server">

My Title Goes Here


You extract 'My Title Goes Here' into the Resource file and let's say you give it a key 'Page_Title'. Then, you replace the page content with:
<asp:content id="PageTitle"


<asp:Literal ID="literal" runat="server"
Text="<%$ Resources:WarehouseManagement,Page_Title %>" />


Note that you can't just have '<%$ Resources:WarehouseManagement,Page_Title %>' standing alone. This code either has to be embedded into another control's property (Text, HeaderText, ErrorMessage, etc) or it has to be in a placeholder, which in this case is asp:Literal.

You need to do this for every text you want to localize.

Also, every page you are localizing, has to have those two attributes in the 'Page' node: Culture="auto" UICulture="auto". Example:
<%@ Page Language="c#" MasterPageFile="~/_layouts/WarehouseManagement.master" Inherits="TestPage, WarehouseManagement, Version=, Culture=neutral, PublicKeyToken=[token]" Culture="auto" UICulture="auto" %>

3. Second language
Once you are done moving your text into the resource file, you can make a copy of your resource file. Since we are localizing to Hungarian, rename the copy of the file to WarehouseManagement.hu.resx. Open the resource file for editing and translate the entries from English to Hungarian.

You have to keep the two resource files in sync. If you delete keys, add new ones or rename in one of them, the other one has to reflect it too.

4. web.config change
Make sure you have this node in your site's web.config file:
<globalization fileencoding="utf-8"

uiCulture="auto" culture="auto" />

5. Deployment
Those resource files need to be deployed to your site's App_GlobalResources folder. This usually is: C:\Inetpub\wwwroot\wss\VirtualDirectories\[Port Number]\App_GlobalResources

6. Language Preference
So how exactly do you set the language preference? How do you tell the page which localization (English or Hungarian) you want to see? That's easy. Go to your browser's Language setting and set your preference.

For IE:
Tools -> Internet Options -> General Tab -> Languages -> Add / Move Up / Move Down

For FF:
Tools -> Options -> Content tab -> Languages (bottom) Choose button -> Add / Move Up / Move Down

Your browser provides the page what is your language preference, by sending an appropriate header. So, at this point, what happens when the page renders? Browser sends the page request, along with the language preference header. ASP.NET replaces the resource reference with the actual value, from the appropriate resource file.

How ASP.NET determines which one is the appropriate resource file? Easy. Let's say your first language preference is Arabic, second is Hungarian and third is English. You open the page, ASP.NET tries to find arabic localization file but fails, then it tries to locate Hungarian localization file - it is found and it is determined as the appropriate one to use.

What happens if your only language preference is 'Arabic' (and in our case, we don't have localization for it)? We send the request, ASP.NET doesn't find the right localization and since you don't have other language preferences, it falls back to the default resource file, which is WarehouseManagement.resx and happens to be in English.

This gives you the ability to 'plug and play' new language localizations by simply copying one of the existing .resx files, give it a proper extension (depending on the language you are localizing to), translate the content and deploy it to the right location. You won't need to change anything on your pages.

Also, note that this architecture allows every client of the web application to set language preference for himself, rather than you, setting the language translation globally for the whole site and every user.

For automation of the deployment of resource files, you may want to look into this blog post:

SharePoint Resources, Types, Use and Deployment

Bookmark and Share


richard said...

Hristo, thank you for your article. Is possible you include source code that I can play with?

Thank you,

HY said...

Hi Richard,

I have decided to extend this post into a two part step by step tutorial.<

The first part explains the basics of creating a sample SharePoint project.

The second discusses the specifics of the page localization.

Please check it out.