Hosted by Three Crickets

Diligence
Web Framework
For Prudence and MongoDB

Diligence is still under development and incomplete, and some this documentation is wrong. For a more comprehensive but experimental version download the Savory Framework, which was the preview release of Diligence.

Diligence logo: sleeping monkey

Internationalization Service

This is a straightforward but powerful service that lets you render text by key from "text packs" per locale.
A single application can load many text packs simultaneously, such that every user could see text in their preferred language, if you support it. Text packs can be cached in memory (in the application globals) once loaded, while giving you control over the cache duration in case you want to enable on-the-fly editing of text packs.
Importantly, this service supports bi-directionality (left-to-right or right-to-left languages) by keeping track of the direction of every single key. This is crucial, because you may have to render left-to-right and right-to-left text on the same page, and you want to make sure that each key is rendered correctly.
Text packs can inherit each other, making it easy to manage many text packs with a common base, or to merge text packs from different sources into one. For example, you can you have a general English text pack, and the a British English text pack, which inherits the general English text pack and only overrides those keys that are different. Directionality of keys is maintained: if a right-to-left Arabic text pack inherits an English text pack, those left-to-right keys from the English text pack will stay left-to-right.

Setup

Text packs are looked for first JSON files and then in a MongoDB collection called "textpacks". You can combine text packs from both, and inherit either from the other.
The text pack is a dict that must include at least a "text" key, with a structure of any depth, and optionally a "direction" key, which could be either "ltr" (the default, for left-to-right, the default), or "rtl" (for right-to-left languages). Additionally, you can add an "inherits" key, which can be either a single locale specification or an array of locale specifications, which specifies which text packs should be merged into this one. The values of the inheriting text pack will always override those from the inherited text packs.

Locale Specifications

In all the following examples, whenever you need to specify a locale you can specify it either as a string signifying the language or in full form, with "language", "country" and "variant" keys. For example, these two locale specifications would be considered equivalent:
"en" == {"language": "en"}
But this locale would be different:
{"language": "en", "country": "nz"}

As MongoDB Documents

Text packs will be found in the collection called "textpacks". They have the same structure as the JSON files, but must also have a "locale" key, with the locale specification as detailed above. Here's an example document:
{
	_id: ObjectId("4d6803e6ddfe99e799c7b809"),
	"locale": {
		"language": "en",
		"country": "nz"
	},
	"direction": "ltr",
	"inherit": "en",
	"text": {
		"application": {
			"myapp": {
				"time": "It is now {now}"
			}
		}
	}
}
Again we'll emphasize: even though this text pack is defined in MongoDB, it can inherit the "en" text pack defined in the JSON file.
You'll usually prefer one method or the other, but it might make sense to use both: for example, a default text pack can be hard-coded for your application, to allow it to function even if MongoDB is not available.

As JSON Files

If stored in files, the name of the file must be in the form "[locale].json". For example, for the English locale it is "en.json". If the locale has country and variant specifications, they are added with underscores. For example, English/New Zealand would be "en_nz.json".
An example "en.json" file:
{
	"direction": "ltr",
	"text": {
		"application": {
			"myapp": {
				"time": "It is now {now}"
			}
		}
	}
}

Per-User Text Packs

See the "Authentication Service."

Usage

Here's an example:
<%
document.executeOnce('/diligence/service/internationalization/')
var textPack = Diligence.Internationalization.getPack('en')
%>
<p dir="<%= textPack.getDirection('application.myapp.time') %>">
	<%= textPack.get('application.myapp.time', {now: new Date()}) %>
</p>
​
var textPack = Diligence.Internationalization.getCurrentPack(conversation)
The "get" method will automatically cast templates. In this case, our text is a template in the form of "It is now {now}". The "getDirection" method will return either "ltr" or "rtl" according to the directionality of that specific key.

Attaching a Text Pack to the Conversation

In many cases, you would not want to specify the locale explicitly, but instead would want it loaded from, say, the logged-in user's stored preferences. In that case, you can store the selected locale in the conversation.locals as "diligence.service.internationalization.pack", or use this shortcut:
textPack.setCurrent(conversation)
And then retrieve it like so:
var textPack = Diligence.Internationalization.getCurrentPack(conversation)
Many of Diligence's other services and features rely on this API call, so make sure to set up the conversation.local appropriately if you want them to support internationalization.

Configuration

In your application's "settings.js", add something like this to your app.globals:
app.globals = {
	...
	diligence: {
		service: {
			internationalization: {
				defaultLocale: 'en',
				cacheDuration: 10000, // in milliseconds; if 0 (the default) will never cache
				path: Sincerity.Container.getFileFromHere('textpacks') // optional
			}
		}
	}
}
It would then look for ".json" files in the "/textpacks/" directory under your application's main directory.
To signify the locale in full form during configuration, make sure to use the "." key to avoid flattening of the dict (see Sincerity.Objects.flatten). For example:
defaultLocale: {.: {language: 'en', country: 'nz'}}

The Diligence Manual is provided for you under the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. The complete manual is available for download as a PDF.

Download manual as PDF Creative Commons License