How to localize SharePoint hosted Apps for SharePoint 2013 with JQuery

Concept

If you're developping SharePoint 2013 Apps, may be like me you are interested about best solutions to localize your apps.

First, I recommend to read the following MSDN link : How to Localize apps for SharePoint: https://msdn.microsoft.com/en-us/library/fp179919(v=office.15).aspx

This article presents some things to consider to create apps with different languages.

Please note that I will speak about the localization of SharePoint hosted apps only.

For this kind of apps, you must use resources files with Javascript. With "classical" old SharePoint dev models, you used Resources.resx files with C# wrapper to get values. But with Apps, this kind of files could not be use anymore in your developments because you can not write server side code.

So the MSDN article give you a technicle to write localized pages.

This technicle is simple :

  1. Create Resources.XX-XX.js file with lables in vars
  2. Include the good resources files in your html page

The MSDN article preconize the following code :

In the ASPX (or HTML) page, include Javascript with the following pattern:

<script language='javascript' src='Resources.<%$Resources:wss,language_value%>.js'>
</script>

After JS inclusion, you can use the localized labels contained in the JS file to map it on a HTML control. For example:

<h1 id="boo2">This is the invariant language title.</h1>
<script language="javascript">boo2.innerText = homePageTitle;</script>
 

Ok, this technicle seems to work, but in my opinion, this is not the best way to do that.

This method has a lot of disadvantages :

  1. If you haven't define a JS file with the current language, you will not have translation, and your page will be empty, or you will throw a new JS exception 
  2. You can not define a default language
  3. The pattern <% %> could not be use everytime in your pages because of security restrictions
  4. If the resource is available in the same language with different regional settings (example: en-uk and en-us), you don't propose to use the other file
  5. This method doesn't use the SPLanguage query string parameter
  6. Etc.

For all these reasons, I propose to you another method based on Javascript and JQuery to do the same thing.

 

Step #1: create your JS resources files

First, I recommend to add scripts references to JQuery and to a custom Resources.js file. This file will be responsible for including the good resources JS file.

<script type="text/javascript" src="../Scripts/jquery-1.6.4.min.js"></script>

<script type="text/javascript" src="../Scripts/Resources.js"></script>

Now, create two resources files, called for example Resources.en-us.js and Resources.fr-fr.js. Your solution should be something like that:

Open in edit mode the file called Resources.en-us.js, and declare in this file all your English labels with JS vars, like for example:

Now edit your Resources.fr-fr.js file, and declare the same variables, but with french values, like for example :

OK, now open in edit mode the Resources.js file. This file must contain all the logical to load the good Resources.XX-XX.js file. I propose the following code to do that:

// Init vars
var defaultLanguage = 'en-us';
var languagesArray = ['en-us', 'fr-fr'];

// Read a page's GET URL variables and return them as an associative array.
function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = decodeURIComponent(hash[1]);
    }
    return vars;
}

var queryString = getUrlVars();
var language = queryString["SPLanguage"];
if (language == null)
{
    language = defaultLanguage;
}
else
{
    language = language.toLowerCase();
    var langExists = false;

    //Checks if this language is available
    for (var i = 0; i < languagesArray.length; i++) {
        var testedLang = languagesArray[i];
        if (testedLang == language) {
            langExists = true;
            break;
        }
    }

    //Try to find the regional language
    if (langExists == false) {
        var regionalLng = language.substring(0, 2);
        for (var i = 0; i < languagesArray.length; i++) {
            var testedLang = languagesArray[i].substring(0, 2);
            if (testedLang == regionalLng) {
                langExists = true;
                language = languagesArray[i];
                break;
            }
        }
    }

    //Finally use the default language
    if (langExists == false) {
        language = defaultLanguage;
    }
}

var resourcesFile = '../Scripts/Resources.' + language + '.js';
document.writeln("<script src=\"" + resourcesFile + "\" type=\"text\/javascript\" language=\"javascript\"><\/script>")

 

 

Step #2: Add localized labels in your pages

Now in your page, the adapted resources file is loaded in the current language. So you need to use javascript code to translate labels Inside the page.

I propose a JQuery method to do that, based on html tag id attribute. For example, if you want to localized a h2 tag content:

<h2 id="texttotranslate"></h2>
<script type="text/javascript">$('#texttotranslate').append(Resource_Localized_Text);</script>

 

With this method, you can translate page title too for example:

<script type="text/javascript">$(document).attr('title', Resource_Page_Title);</script>