Let's consider a scenario of an Add-in development, it can be either SharePoint hosted or provider hosted. If we are looking for a localization, there are couple of approaches. If you are writing more ASP.net based add-in driven by code behind then resource files comes handy. This is more an old-school type, we have been doing this over decades and I not going to detail anything on this. More details can be found here - https://msdn.microsoft.com/en-us/library/office/fp179919.aspx. Approaches detailed on this article also includes JavaScript based one, I have tweaked this approach in a more reusable format. OK let's get into the action.
How to use it?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%-- The following 4 lines are ASP.NET directives needed when using SharePoint components --%> | |
<%@ Page Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" MasterPageFile="~masterurl/default.master" Language="C#" %> | |
<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> | |
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> | |
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> | |
<asp:Content ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server"> | |
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js"></script> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> | |
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> | |
<script src="../Scripts/localizer.js"></script> | |
</asp:Content> | |
<%-- The markup in the following Content element will be placed in the TitleArea of the page --%> | |
<asp:Content ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server"> | |
<span localeval="PageTitle"></span> | |
</asp:Content> | |
<%-- The markup and script in the following Content element will be placed in the <body> of the page --%> | |
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server"> | |
<div> | |
<div class="jumbotron"> | |
<h1 localeval="HeaderText"></h1> | |
<p localeval="ParaText"></p> | |
<p><a class="btn btn-primary btn-lg" href="#" role="button"><span localeval="BtnTextLearnMore"></span></a></p> | |
</div> | |
</div> | |
<script type="text/javascript"> | |
localizer.Init(); | |
</script> | |
</asp:Content> |
- Add localizer JS to your web page
- Create JS resource files in the file name format resource.<<ll-CC>>.js, sample resource file has been shared below
- Add the attribute localeval="<<ResourceString>>" to the DOM elements, like <h1 localeval="HeaderText"></h1>
- Use localizer.Init() method
How it works?
User identifies the string literals which are to be MUI and adds localeval attribute to the element with string identifier as the value. Individual resource files are created for all supported languages, and contains actual content in that language against the identifier as a set of array items. Sample resource file is given below. Localizer JS queries through the elements with the localeval element and matches the content based on the string identifier and appends the content to that element. Localizer JS selects the resource file based on the SPLanguage query string passed by the add-in as part of the standard tokens. Make sure that {StandardTokens} parameter added in the add-in app-manifest. By default "en-US" is will be set as language if the resource file is missing. The default language can be overwritten by passing the defaulLang parameter in the <<ll-CC>> format. Resource JS file is getting loaded dynamically and also getting cached for by default, set cache: false to override caching.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
localizer.Init({ | |
defaultLang: 'fr-FR', | |
cache: false | |
}); |
Sample resource file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var resources = []; | |
resources.PageTitle = "localisation échantillon"; | |
resources.HeaderText = "Bonjour le monde!"; | |
resources.ParaText = "Ceci est une unité de héros simple, un composant simple jumbotron style pour appeler une attention particulière aux contenus ou informations sélectionnée."; | |
resources.BtnTextLearnMore = "Apprendre encore plus"; |
Code Repo
It's a open source project available in GitHub, feel free to fork, star it, raise pull/merge requests and add issues. I'm happy to collaborate, Together we can make it better. https://github.com/rjesh-git/Localization
App for Testing
Also shared the sample SharePoint hosted app directly from the NAPA cloud tools, which will help to compile and deploy site if you already have an subscription. Pre-compile app can be downloaded from here for your on-premises server.
Thoughts
I have been using this approach, since the other documented approaches are quite messy around setting values for the elements from the resource file. Not a huge fan of having script tag embed between each DOM elements. Also needed a more clean pattern which can be easily reused in multiple projects. This method offers more flexibility when used along with libraries like Angular, KnockoutJS and others. There might be better option, but its a worth a choice.
Happy Coding! Peace.
Comments
Post a Comment