How to: Localize apps for SharePoint
Published: July 16, 2012
Localize an app for SharePoint by using resource files, JavaScript resource files, and other techniques.
Applies to: apps for SharePoint | Office 365 | SharePoint Foundation 2013 | SharePoint Server 2013
The following will help you prepare for the procedures in this article:
-
Set up a SharePoint development environment for apps. For more information, see Start building apps for Office and SharePoint.
-
The code examples and screen shots in this article are taken from the sample Localize the app web, host web, and remote components of an app on Code Gallery. You can download the sample to see the results of the procedures described in this article.
-
Decide which locales your app needs to support. Language Packs in SharePoint let you create websites in a specific language and culture, and not just in a generic language. For example, a website created in English matches the en-US language and culture, but not en-GB. In the same way, a website created in Spanish matches the es-ES language and culture, but not es-MX.
-
Identify the components that you need to localize in your app.
Core concepts to know for localizing apps for SharePoint
Before you localize an app for SharePoint, you should know about the distinction between app webs and host webs, the structure of app packages, the basics of localization with .resx files, and of course, how to build apps for SharePoint.
|
Article title |
Description |
|---|---|
|
Host webs, app webs, and SharePoint components in SharePoint 2013 |
Learn about the distinction between host webs and app webs. Learn also about which SharePoint 2013 components can be included in an app for SharePoint, which are deployed to the host web, which are deployed to the app web, and how the app web is deployed in an isolated domain. |
|
Explore the app manifest and the package of an app for SharePoint |
Learn about the manifest file in the app package of an app for SharePoint. |
|
Learn how to create a basic provider-hosted app with the Office Developer Tools for Visual Studio 2012, how to interact with SharePoint 2013 sites by using the SharePoint client object model, and how to implement OAuth in an app for SharePoint. |
|
|
Learn how to create a basic SharePoint-hosted app using Office Developer Tools for Visual Studio 2012. |
|
|
Learn how to create a basic autohosted app using Office Developer Tools for Visual Studio 2012, how to interact with SharePoint websites by using the REST/OData web service, and how to implement OAuth in an app. |
|
|
Learn about the conventions that SharePoint uses to package apps for SharePoint. |
|
|
Learn the basics of using .resx files for localization. |
To localize components that are deployed to an app web, you add .resx files as local resources in the Feature that contains the components, and then reference the resources in the markup of the component. (For more information about the kinds of SharePoint components that can be in an app for SharePoint, see Types of SharePoint components that can be in an app for SharePoint.) However, custom site pages in an app for SharePoint use JavaScript string variable files instead of .resx files, as described later in this section.
Note
|
|---|
|
Resource files cannot be shared by multiple app web Features. For each Feature in the .wsp file, you have to create separate sets of resource files. |
To create the app web resource files
-
Open the app for SharePoint project in Visual Studio 2012.
-
In Solution Explorer, open the shortcut menu for the Feature name, and choose Add Feature Resource.
-
In the Add Resource dialog box, choose Invariant Language (Invariant Country), and then choose the OK button. A Resources.resx file is added to the Feature's folder in Solution Explorer, and the file is opened in the Visual Studio Resource Editor.
When edited, this "invariant language" file contains the strings that are used in the Feature gallery on all sites in languages for which you are not going to be providing a localized version of strings. So the language used for the strings in this file should be the language that is most likely to be a second language of people using SharePoint. Traditionally, English is used for this purpose, but in some scenarios another language might be a better choice. For example, in some regions, French may be a more common second language of the users than English. The continuing example in this topic uses English as the invariant language.
-
In the Name column of the top row in the Resource Editor, enter a descriptive name for the string (or other resource)—for example, OrdersListInstance_Title and OrdersListInstance_Description. These names of localizable resources are not themselves localized. You cannot use the same name more than once in the file.
-
In the Value column, enter an appropriate string (or URL or other resource) in the invariant language—for example, Orders, and A list to store the orders.
-
Repeat this process until you have rows for every localizable string and resource in any of the components in the Feature.
-
Save the file. The following image shows the localized strings in the resource file for the invariant language.
Figure 1. Resources.resx file for an app web Feature
-
Add another resource file to the Feature as you did before, but select a particular language instead of Invariant Language (Invariant Country). For example, you can choose Spanish (Spain). A Resources.LL-CC.resx file (where LL and CC are Internet Engineering Task Force (IETF)-compliant language and culture codes) is added to the Feature's folder in Solution Explorer, and the file is opened in the Visual Studio Resource Editor.
-
Using the Resource Editor, copy all the rows from Resources.resx, and paste them into the new Resources.LL-CC.resx file.
-
In the Resources.LL-CC.resx file, replace the Value cells with translated versions of the string values. For URLs and other non-string resources, replace the value with a new value that is appropriate for the language and culture.
-
Save the new file.
-
Repeat the last four steps for each foreign language.
Note
You should consider adding a language-specific file for the same language as your invariant language. If you do, you can copy the rows without changing the values of the strings. In many situations, it is not necessary to have a language-specific file for the same language that is used in the resource file for the invariant language, especially when the only resources in the files are strings. But resource files can contain images, icons, files, and other kinds of resources too. Sometimes, you need the invariant language resource file to use an image or other resource that is different from the corresponding resource in any of the language-specific files.
-
For each file, verify that the Build Action property is set to Content.
To call the localized resources in custom lists
-
To localize the title and description properties of the custom list, open the Elements.xml file of the instance of the list.
-
In the Title box, enter $Resources:StringName, where StringName is the name, not the value, you gave in the previous procedure to the string that names the custom list—for example, $Resources: OrdersListInstance_Title. Note that, unlike in some contexts where .resx files are used, the resource file name is not part of what you enter.
-
Use the Description box to call the string resource of the list description in the same way—for example, $Resources:OrdersListInstance_Description. The following is the markup that uses the localized strings in the Elements.xml file of the instance of the list.
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <ListInstance Title="$Resources:OrdersListInstance_Title" OnQuickLaunch="TRUE" TemplateType="10000" Url="Lists/Orders" Description="$Resources:OrdersListInstance_Description"> </ListInstance> </Elements>The following image shows the localized custom list in English.
Figure 2. A localized custom list
You can’t localize the column names of the custom list in the same way as you localize the title and description. To localize the column names, you have to declare the list fields in an Elements.xml file, and substitute the DisplayName attribute value with the strings in the app web resource files. You can use the Elements.xml file that Visual Studio provisions for you when you add a custom list.
To localize the column names of a custom list
-
Open the Schema.xml file of your custom list. Locate the Fields node and copy all its Field nodes.
-
Open the Elements.xml file of your custom list. Make sure you open the Elements.xml file of the list definition, and not of the instance of the list. Paste the nodes from the previous step as children of the Elements node.
For every Field node, enter a value of $Resources:StringName in the DisplayName attribute where StringName is the name of an entry in the app web resource file.
-
In the Schema.xml file of your custom list, remove the DisplayName attribute of every Field node that you previously copied. The following is an example markup that uses the localized strings in the Elements.xml file of the list definition.
<?xml version="1.0" encoding="utf-8"?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <ListTemplate Name="Orders" Type="10000" BaseType="0" OnQuickLaunch="TRUE" SecurityBits="11" Sequence="410" DisplayName="Orders" Description="My List Definition" Image="/_layouts/15/images/itgen.png"/> <Field Name="Bookname" ID="{2ef60a05-29b6-41db-9611-c0cf7d8e73c5}" DisplayName="$Resources:OrdersListColumn_Bookname" Type="Text" Required="TRUE" /> <Field Name="Price" ID="{7af42815-d69e-426a-a1c8-9da5610e362c}" DisplayName="$Resources:OrdersListColumn_Price" Type="Currency" Required="FALSE" /> <Field Name="Orderstatus" ID="{687ee751-2e0a-4099-966e-d2c225d48234}" DisplayName="$Resources:OrdersListColumn_Orderstatus" Type="Lookup" Required="FALSE" List="Lists/Order status" ShowField="Title" /> </Elements>
To create JavaScript resource files for custom pages
-
In Solution Explorer, open the shortcut menu for the Scripts node, and add a new JavaScript file using the JavaScript file template in Visual Studio 2012. Name the file Resources.LL-CC.js (where LL is a language code and CC is a country/region or culture code); for example, Resources.en-US.js.
-
Repeat the preceding step for each foreign language. You should now have blank JavaScript files for every language. Do not create an invariant language file named "Resources.js". The reason is explained in a later procedure.
-
Open the first of the new JavaScript files.
-
For each localizable string in each of your custom pages, declare a variable in the file with a name that identifies the purpose of the string and assign it a value that is appropriate for the language. The following is the contents of the Resources.en-US.js file.
var instructions = "Instructions:"; var step01 = "Go to any document library in the host web."; var step02 = "Go to the Library tab."; var step03 = "Click \"Request a book\" in the Settings group."; var step04 = "Click the contextual menu in any document."; var step05 = "Click \"Buy this book\" in the contextual menu."; var step06 = "Go to any SharePoint page in the host web and add the" + " Bookstore orders app part."; var step07 = "Review the localized <a href=\"../Lists/Orders\">Orders</a>" + " and <a href=\"../Lists/Order status\">Order status</a> custom lists.";
-
Copy the contents of the file into each of the remaining JavaScript files, and then save all files.
-
In each file, replace the value of each variable with a new value that is appropriate to the language of the file. Do not change the variable names.
To call the localized variables in custom ASPX pages
-
In Solution Explorer, open a custom ASPX page file.
-
You need to make sure that only one of the localized JavaScript files is loaded when your page loads, and it should be the one that is appropriate for the language of the SharePoint app web. To do this, add the following markup to the head element of the page. There are no placeholders in this markup. Enter the markup exactly as it appears here.
This markup loads one of your JavaScript files. It determines which language file to load by reading the SharePoint resource named "language_value." This resource resolves to a language-culture name in the pattern LL-CC that was described in an earlier procedure. Specifically, it resolves to the language of the app web.
<script type="text/javascript" src="../scripts/Resources.<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,language_value%>' EncodeMethod='HtmlEncode' />.js"></script>
Note
The SharePoint resource "language_value" is never null, so a file named "Resources.js" is never called by this script. That is why you did not make one in the preceding procedure. When the value of "language_value" is a language for which there is no .js file, this script loads nothing. The next step explains how localized strings get an invariant language value in that situation.
-
For each localizable element and attribute value on the page, give it a default value in the invariant language, but then use JavaScript to assign it the appropriate variable from the Resources.LL-CC.js file. For example, if the page has a title in an h2 element, give the element an id attribute and then insert a script element below the h2 element to assign a localized string to its innerText property. The following is an example.
<h2 id="instructions"></h2> <ol> <li id="step01" /> <li id="step02" /> <li id="step03" /> <li id="step04" /> <li id="step05" /> <li id="step06" /> <li id="step07" /> </ol> <!-- Use the localized strings in the resource JavaScript file --> <script type="text/javascript"> window.onload = function () { document.getElementById("instructions").innerText = instructions; document.getElementById("step01").innerText = step01; document.getElementById("step02").innerText = step02; document.getElementById("step03").innerText = step03; document.getElementById("step04").innerText = step04; document.getElementById("step05").innerText = step05; document.getElementById("step06").innerText = step06; document.getElementById("step07").innerHTML = step07; } </script>
The following image shows the page using the localized strings in English:
Figure 3. A webpage using localized strings from a JavaScript resource file
You can localize the app title, which is specified in the AppManifest.xml file. This is what users see on the Your Apps page. The host web for an app for SharePoint can also include a custom action, an app part, or both. These are deployed in a host web Feature. Both of these components can have localizable strings.
The essential method for localizing host web components is the same as for localizing app web components: localized resources are itemized in a .resx file and are called from the markup files. However, Office Developer Tools for Visual Studio 2012 does not have as much tooling support for the process as it applies to host web features. There is a manual process involved that is explained later in this section.
To create the host web resource files
-
In Solution Explorer, choose the AppManifest.xml file to open the app manifest designer tool.
-
Open the Supported Locales tab.
-
In the top blank cell of the Locales column, open the drop-down list and choose the first locale that you want to support. Two files are created and added to the app for SharePoint project: Resources.resx, which is the invariant language resource file, and Resources.LL-CC.resx, which will contain the localized resources. Don’t change the names of these files.
-
Repeat the previous step for each locale you want to support. An additional Resources.LL-CC.resx file is created for each locale.
Note
The Build Action property of each of these files is set to Content, not Resource. Don’t change this setting.
-
Open the Resources.resx file and add resource names and values to the file just as you did for the app web resource files. At a minimum, you should have a resource for the app title. If your app for SharePoint includes a host web custom action or app part, you also need resources for the host web Feature title and the host web Feature description. If the Feature has a custom action, you need a resource for the Title attribute of the CustomAction element, and possibly other strings in the custom action markup. If there is an app part, you need resources for the Title and Description attributes of the ClientWebPart element. If the app part has custom properties, each Property has an attribute that should be localized as well. For each of these, you need a row in the resources file.
-
Copy the contents of the Resources.resx file into each of the Resources.LL-CC.resx files.
-
Localize each resource in each Resources.LL-CC.resx file just as you did for the app web resource files. The following image shows an example Resources.resx file.
Figure 4. A resource file for host web features
To call the localized resources in the app manifest, and other XML files
-
Open the AppManifest.xml file and replace the Title element value with a call to the appropriate resource string. For example, if you named the string AppTitle, the Title element should look like the following:
<Title>$Resources:AppTitle;</Title>
Caution
The value of Title can contain only the call to the resource. There can be no other text, symbols, or white space.
-
To call localized resources in other XML files, such as Elements.xml for app parts and custom actions, you use the same format that you used in the app manifest file.
However, Visual Studio does not add the OPC (Open Packaging Conventions) relationships between the resource files and features, such as app parts and custom actions. The following image shows an app part that does not have the relationships to the resource files.
The following procedure shows how to manually add the OPC relationship to the app package.
To add OPC relationship markup to the app package
-
Append a .zip extension to the app package.
-
In the .zip file, open the folder named _rels.
-
Open the AppManifest.xml.rels file. This file specifies the OPC relationships of the AppManifest.xml file to other files in the package. The file contains a Relationship element for the Resources.resx file and for each of the Resources.LL-CC.resx files. The following are examples:
<Relationship Type="http://schemas.microsoft.com/sharepoint/2012/app/relationships/content-defaultresource" Target="/Resources.resx" Id="R8d5c4429fc13446e" /> <Relationship Type="http://schemas.microsoft.com/sharepoint/2012/app/relationships/content-resource" Target="/Resources.en-US.resx" Id="R71986f3a45e24d8f" />
-
Copy these resource-related Relationship elements and save them in a text file outside the package so you can reuse them in a later step.
-
Close the AppManifest.xml.rels file.
-
In the _rels folder, open the featureGUID.xml.rels file. This file specifies the OPC relationships of the featureGUID.xml file and all its child files, such as elements.xml files, to other files in the package.
-
Paste into the Relationships element all of the Relationship elements that you copied from the AppManifest.xml.rels file. It’s OK to use the same relationship IDs because you are pasting them into a different parent Relationships element.
-
Save (as UTF-8) and close the file.
-
Close the .zip file and then remove the ".zip" from the end of the file name. The app package can now be installed on your test SharePoint website.
The previous procedure prevents you from using F5 in Visual studio. Alternatively, you can build a tool that adds the OPC relationships. You can use this tool in the pre-deployment event of the app project. The companion code sample includes a tool named AddRelsToAppPackage.exe. The following image shows the pre-deployment event using the AddRelsToAppPackage tool.
You localize the Windows Azure Web Site components that are included in an autohosted app just as you would any other ASP.NET application. The associated resource files are included in the Web Deploy 2.0 package inside the app for SharePoint package. For more information, see ASP.NET Globalization and Localization. (If the Windows Azure Web Site components are PHP or other non-Microsoft formats, see the localization instructions for the appropriate platform.)
You should override the page language to match the language of the host web. You can use the SPLanguage token in the InitializeCulture method of your ASP.NET pages. The following code shows how to override the page language.
protected override void InitializeCulture() { if (Request.QueryString["SPLanguage"] != null) { string selectedLanguage = Request.QueryString["SPLanguage"]; UICulture = selectedLanguage; Culture = selectedLanguage; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(selectedLanguage); Thread.CurrentThread.CurrentUICulture = new CultureInfo(selectedLanguage); } base.InitializeCulture(); }
You localize the provider-hosted components of an app by using the techniques appropriate to the particular platform stack against which you are developing the components.
You can test your app by deploying it to a SharePoint website that is provisioned in one of the languages supported by your app. You can test your app on a SharePoint Online website or an on-premises website.
To test your app on a SharePoint Online website
-
Go to your Office 365 admin center.
-
Choose service settings on the navigation menu, and then choose sites.
-
Under site collections, choose Create site collection.
-
Under select a language, select the language in which you want to test your app.
-
Under select a template, choose Developer Site.
-
In your app for SharePoint project, update the SiteUrl property with the URL of the recently created site collection.
The following image shows the create site collection page.
To test your app an on-premises website
-
Install the language pack in which you want to test your app. For more information, see Install or uninstall language packs for SharePoint 2013.
-
Go to your on-premises farm Central Administration site.
-
Under Application Management, choose Create site collections.
-
Under select a language, select the language in which you want to test your app.
-
Under select a template, choose Developer Site.
-
In your app for SharePoint project, update the SiteUrl to the URL of the recently created site collection.