logo

Lingua Localization

The Lingua Localization jQuery Plugin makes it fast and easy for developers to translate web user interfaces into other languages and handle many other localization-driven concerns. The high-level description is that it loads plain-text key-value pairs from files which are named according to the language they contain. Developers can use this to store the raw text which goes into the user interface, internal text such as alert-box content, or even flags and other textual data that is language-driven.

The plugin is also able to automate some of the chores associated with updating the user interface when a new language is loaded. If the key portion of the key-value pair is preceded with a # symbol, this indicates the key is an HTML element ID selector. In this case, the plugin can automatically replace the HTML contents of the element with the values from the newly loaded language file. If you change languages on this documentation site, that feature is how the change is made. (Unfortunately, I am only fluent in English, so Google Translate was used for the other languages. I assume the translations are terrible!)

Although this page is being translated using Lingua, it is actually not optimized for large blocks of text. The key-value pairs in the translation files are currently limited to a single line, which makes it more difficult to maintain large bodies of text and markup. I am planning to add support for simple block start/stop markers which should help alleviate this problem. Lingua by itself also doesn't address more complex translation issues light text direction, mainly because of the added complications of designing other parts of the page, which is far beyond the scope of the plugin and this documentation.

I would also like to briefly comment on the design of Lingua. I chose to hang the Lingua methods directly off the jQuery object. This is considered "polluting" the jQuery namespace. However, the usage is far more natural, and I rather suspect few real-world applications will actually have a collision with a method name like "linguaLoadAutoUpdate". I'm usually a sucker for a good theoretical argument, but please, don't e-mail me about this one. The source is simple, open, and free; if you really prefer to specify your method names as a parameter, it should take about ten minutes to customize the plugin to your liking.

I would like to thank Keith Wood for his Localisation plugin, and Acatl Pacheco for his ResourceBundle plugin. These two plugins provided much of the inspiration which led me to create Lingua.

Translation Files

Translation files are plain-text files. You will almost certainly need to create them as Unicode files to properly support foreign-language charactersets, and of course, your web pages should also specifiy a Unicode encoding (probably UTF-8) in a meta-tag. Such technical details are beyond the scope of this documentation, but some useful links are provided after the text. If you see lots of "�" symbols in your language files or UI, you don't have the encoding right yet.

You should create one file to act as your "default" content. For example, the English version of this content is stored in a file named "docs.txt" and if the code tries to load a language which doesn't exist, this is the file which will be shown instead. Copies of your default file can then be translated into other languages. The language-specific files should be named by appending a dash and the standard language code which matches the content. For example, the German version of this content is stored in a file named "docs-de.txt" because "de" is the language code for German (derived from German's own name of the language, Deutsche). The language files are retrieved in the background using AJAX, so there is no server round-trip or other overt page refresh to distract your user.

The translation files MUST be named with a ".txt" extension. In other words, the valid patterns are:

  • filename.txt
  • filename-en.txt
  • filename-en-US.txt

You could als use regional dialects such as "docs-en-AU.txt" to indicate an Australian English file. If Lingua tries to load a dialect which is not present, it will automatically try the generic version (just "en" instead of "en-AU"), and failing that, it will load the default file.

The file contents are simply key-value pairs separated by whitespace (tabs or blank spaces). You can include comments in your translation files by inserting marks (//) as the first characters on the line. Comment lines and blank lines are ignored. For all other content, the first word on the line is the key, and the remainder of the line is the value. Whitespace is stripped from both parts. Keys are case-sensitive. When the key portion of a key-value pair is prefixed by a hash (#) character, this tells Lingua that the key is actually the name of an element ID. These entries are stored in a different place for automated processing by Lingua. You will not be able to directly retrieve content with a selector key.

A simple default language file might look like this:

// default file
one One is 1
two Two is 2
three Three is 3
#title Your First Three Numerals

If you load this file (which is not language specific, because it is the default) and retrieve the "three" key, Lingua will return "Three is 3" as you have probably already guessed. If you tell Lingua to auto-update the HTML elements, it will look for an element with ID="title" and set the HTML contents of that element to the text "Your First Three Numerals". If you try to retrieve the key "#title" or "title" Lingua will return a blank string. The comment line at the beginning of the file is ignored.

The German equivalent of this file would look like this:

// de - Generic German file
one Ein sind 1
two Zwei sind 2
three Drei sind 3
#title Ihre ersten drei Ziffern

So the bottom line is that your code would not change. You will still request the "three" key but now the response would be the German version, and the page title will have automatically updated itself.

Useful links on the topic of multilingual text, Unicode, and so on:

Language Codes made easy: Sharper Tutorials' Culture Code List

The official Language Code document: IETF RFC 4646

Joel on Software: What Every Programmer Needs to Know...

Martin J. Dürst: Collection of Papers and Presentations

Tim Bray on Unicode and Characters vs. Bytes

Wikipedia: Byte Order Mark

$.lingua(key)

This is the syntax used to retrieve a string.

var currencyname = $.lingua("BasicMonetaryUnit");

$.linguaInit(path, name)

This initializes Lingua and should be the first Lingua method executed by the application. The path tells AJAX where and optionally how (http, https) to retrieve the language files. Note that the path is simply used as-is. You MUST ensure it has a trailing slash, for example. You can supply an empty string if the language files are in the same folder as the HTML file. The name is the default file's name EXCLUDING the extension. Again, there is minimal verification -- if either parameter is wrong, it will simply silently fail to load any language file at all. Note this method DOES NOT actually load any file. There is no return value.

$.linguaInit("/motorsports/news/", "story.txt");

$.linguaGetLanguage()

This can be used to retrieve the language code most recently passed to Lingua. It does not indicate that the language code was successfully read, and if Lingua was forced to downgrade to a generic language file (for example, "en-AU" is missing, so "en" was loaded), or downgrade to the default file, this will still return the language code that was originally requested. Also, immediately after calling linguaInit, this will return the web browser's default language. Your application can use this to immediately load the user's preferred language, if you so desire.

var targetlang = $.linguaGetLanguage();

$.linguaLoad(language)

This directs Lingua to load and parse the file for the indicated language code. No other processing takes place and there is no return value.

var browserlang = $.linguaGetLanguage();
$.linguaLoad(browserlang);

$.linguaUpdateElements()

Assuming the language file contained hash (#) prefixed selector keys, this method directs Lingua to apply the values to their respective element IDs. This is done using the jQuery html() method, so the identified elements and the value strings must be compatible with that type of usage. There is no return value.

var browserlang = $.linguaGetLanguage();
$.linguaLoad(browserlang);
$.linguaUpdateElements();

$.linguaLoadAutoUpdate(language)

This simply wraps the loading process with the element update process as a convenience to the programmer. There is no return value.

var browserlang = $.linguaGetLanguage();
$.linguaLoadAutoUpdate(browserlang);

Release History

  • May 20, 2011 - 052011.0001 - Initial Release