How to internationalize javascripts

From Sense/Net Wiki
Jump to: navigation, search
  • 100%
  • 6.0.8
  • Enterprise
  • Community
  • Planned


Sense/Net comes with built-in Localization features to enable users to translate their sites and/or change language settings of pages by a single click. The CMS also provides means for developers to make javascripts localizable. This comes handy when you are developing Ajax features that create Html DOM elements with labels, or simply work with labels.


To access a resource class, simply include the following tag at the very top of the javascript file:

// resource MyClass

This tag must be placed in the same block as all other javascript dependency definitions, like:

// using $skin/scripts/SN/SN.Util.js
// resource MyClass

From here onwards you are able to access the provided string resource keys via the SN.Resources object as simple strings. For example:

// Simple syntax
var labelText = SN.Resources.MyClass.MyKey;
// Alternative javascript syntax (handy when the key contains whitespace or special characters)
var localizedText = SN.Resources.MyClass["My key name"];

The SN.Resource.<className> object contains all the keys that are defined in the CMS for the given resource class for the current language of the portal.

If the requested culture is empty, its parent culture is used, and if that's empty too, the portal's default fallback culture is used.

When using the resource script alongside the resource editor, it may be possible that the changes are not visible immediately. They however will appear correctly if you refresh the page in a few seconds.

As a more convenient approach, it is possible to create wrapper functions for this (eg. to handle non-localized strings or to render markup to work with the resource editor.

The following example shows how to do this. For non-localized strings, it returns the resource key prepended with two exclamation marks (so that one can easily notice that parts they forgot to localize) and it also renders markup that will work together with the resource editor.

function myTranslate(key) {
    var resource = SN.Resources.MyClass[key];
    if ($.cookie('AllowResourceEditorCookie') == null) {
        // If the resource editor is not enabled, just return the key prepended with !! if not localized
        if (resource == undefined || resource == null || resource == '')
            return '!! ' + key;
        return resource;
    // Markup that utilizes the resource editor (if enabled)
    if (resource == undefined || resource == null || resource == '')
        return "<a href='javascript:' onclick=\"SN.ResourceEditor.editResource('MyClass','" + key + "');\"><span style='background-color:#FFFFE6;color:#000;border:1px dashed #333;'>!! " + key + "</span></a>";
    return "<a href='javascript:' onclick=\"SN.ResourceEditor.editResource('MyClass','" + key + "');\"><span style='background-color:#FFFFE6;color:#000;border:1px dashed #333;'>" + resource + "</span></a>";

Although the above markup in the example works with the resource editor in the current Sense/Net version, that markup can be subject to change in later versions.

How it works (after 6.1.1)

For every // resource <className> definition a script tag will be rendered in the page in the following form:

<script src="/sn-resources/[current language]/[class name]" type="text/javascript"></script>

For example:

<script src="/sn-resources/en-US/MyClass" type="text/javascript"></script>

The requested URL will render javascript code which will create the SN.Resources object and fill the members according to the requested class name. The sn-resources URL is handled by a custom HTTP handler.

<add name="snResourceScriptHandler" preCondition="integratedMode" verb="GET,HEAD" path="/sn-resources/*" type="SenseNet.Portal.Resources.ResourceHandler, SenseNet.Portal" />

Therefore to achieve correct behavior you must check that the above handler registration is present in your Web.config file.

Caching (only in newer than 6.1.1)

Newer versions of Sense/Net handle the resource scripts in a cache-friendly way. This means that it sets Last-Modified HTTP headers and is able to handle If-Modified-Since request headers too.

Bundling(only in newer than 6.1.1)

The bundling feature in Sense/Net will work together with the resource script and will incorporate the resource script in the javascript bundle (unless blacklisted).

Note that this did not work in previous versions.

How it worked (applies to 6.1.1 and older)

In Sense/Net 6.1.1 and older releases it used to work in a similar way, however the approach was less flexible.

It used to render the following:

<script src="/Resources.ashx?class=className" type="text/javascript"></script>

The resulting script is almost identical to the newer version, but doesn't support special characters like line breaks or quotation marks in the resource values and class names. The Resources.ashx file was located in the /Root/System/WebRoot folder, and therefore to achieve correct behavior the following must be checked:

  • the users visiting the page running your javascript have necessary permissions to access /Root/System/WebRoot/Resources.ashx,
  • Resources.ashx is enlisted in the web.config's WebRootFiles key.

Related links


This page does not have external references.