Quick links: Content - sections - sub sections

Jelix has its own localization/internationalization mechanism. The setLocale and gettext functions from php are not used because too much constraining to setup, and their configuration is random on servers.


Each text or string that you want to translate is associated to a key, a code. These associations are placed in "properties files". Each properties file is associated to a language and character encoding. The default language and character encoding are configured in the config file of your application.

$lang = $GLOBALS['gJConfig']->locale;

To be able to retrieve a string in the current language, you only have to call jLocale::get('LocaleSelector'), or in the templates use the @LocaleSelector@ syntax (see the page about templates).

Properties files

These are files containing translations. They are located in the locales directory of the modules. This directory has a specific organization. It has sub-repositories for each language. Example: locales/fr_FR/, locales/en_US/, etc. And in each of these sub-directories there are properties files corresponding to the language.

File names

The name of the properties files has the following structure : codefile.charset.properties. Codefile is a codename that will be used in the selectors, and charset corresponds to a character encoding. Example: foo.ISO-8859-1.properties , foo.UTF-8.properties etc.

If in the config file, there is "locale=fr_FR" and "charset=ISO-8859-1", then the fr_FR/foo.ISO-8859-1.properties will be used.

File contents

The file structure is simple : this is a list of key=translated string lines.

Here is an example for a en_US/foo.ISO-8859-1.properties file :

title.offlineElements = elements to check
title.onlineElements = online elements

buttons.save = Save

And the equivalent in French fr_FR/foo.ISO-8859-1.properties :

title.offlineElements = éléments à traiter
title.onlineElements = éléments en ligne
buttons.save = Enregistrer
Multi line

If the text is long and you want to write it in several lines, you have to type an anti-slash (\) in the end of each line (excepted the last one of the text).

intro=this is a very very\
long text in\
several lines

However, it doesn't insert a line break in the string. If you want to insert a real line break, use \n:

intro=this is a very very\nlong text in\nseveral lines

You can also put some comments. They have to begin with a #, the rest of the line won't be then interpreted. A comment can be at the begining of a line, or after a value. If you want to use a # in a value, you have to escape it with an anti-slash.


Whitespaces before and after a value are ignored. Si if you want to put a value equal to a space, you have to use \w

foo= \w

The value of foo will be " ".

HTML entities

Localized strings shouldn't contain HTML entities. First because a localized string could be used for other content than HTML. And second because html response escape some characters for some purpose (example : in the title of an html page). So if the given string contains entities, this entities will be escaped and the browser won't identify them.

If you want to use specific characters (&#xxx; or é etc), choice the correspondant charset and use directly this characters, instead of using HTML entities. This is why it is a good choice to use the UTF-8 charset in your application, since you can use every existing characters in any language.

Retrieving a localized string

To retrieve a string, you have to use the get static method of jLocale. This method accept as the first argument a locale selector, which has the following structure : module~filecode.keystring. the "module~" part optional if this is a file from the current module.

For example, to retrieve the value of buttons.save in foo.ISO-8859-1.properties in the "bar" module :

  $string = jLocale:get("bar~foo.buttons.save");

In a template, this would be for example :

  <input type="button" value="{@bar~foo.buttons.save@}" />

Localized string with parameters

It could be useful to have localized string with dynamic parameters.

For example, you want to write this string:

   You will go on the http://foo.com web site and you will click on the 'car' category.

But you would like to indicate dynamically the url of the web site and the name of the category. You can then pass this dynamic values as parameters to jLocale:

  $string = jLocale::get("bar~foo.sentence", array('http://foo.com', 'car'));

And in the properties file, you have to put a "%s" where you want to insert this dynamic values:

   sentence = You will go on the %s web site and you will click on the '%s' category.

This string is parsed by the sprintf function. So you should follow the syntax accepted by sprintf. For example, the order of the parameter is important.

In particularly, in some language, perhaps the translation causes a change in the order of parameters. But you won't pass the parameters in a different order. So you will use the syntax %x$s where x is the order number. For example, you could have this sentence:

   sentence = Click on the %s section, when you go on the %s web site.

But in an other language, the translator would like to change the order of the parameters (eg. the first parameter in the sentence will be the url web site, not the section name). So for example, in french, he could translate like this:

   sentence = Vous allez sur le site %2$s et vous cliquez sur la rubrique %1$s

So the first parameter will replace "%1$s", the second parameter will replace "%2$s" and so on.

Note that in template, you can use the "@foo@" syntaxe to indicate parameters. So you have to use the "jlocale" plugin:

   <p>{jlocale "bar~foo.sentence", array('http://foo.com', 'car')}</p>

Supporting several language at the same time

Jelix provide a plugin for the coordinator, which allow to change dynamically the language of the web site. This is the "autolocale" plugin (in lib/jelix/plugins/coord/). (see plugins/coord)

The plugin look at the url, and check if there is a specific parameter which indicate the new lang to use (by default, this parameter is "lang"). The code of the new lang is then stored in session, and then the web site will be displayed with this language for the rest of the visit (until there is a new lang parameter with a different language code).

Note that the "locale" configuration variable is also changed, but only dynamically at each request. The configuration file is not modified. So it is totally transparent for you. To know the current locale, you just have to do :

  $lang = $GLOBALS['gJConfig']->locale;

To use the plugin, copy the file lib/jelix/plugins/coord/autolocale/autolocale.coord.ini.php.dist in the var/config/ directory, by renaming it to autolocale.coord.ini.php.

In this file, two parameters are important :

enableUrlDetection= on
availableLanguageCode = fr_FR,en_US

You should have of course to activate the language detection in the url. So you set enableUrlDetection to "on". In availableLanguageCode, you put all language code available in your web site. And the urlParamNameLanguage variable should content the name of the url parameter which wil contain the new language code to use.

So in your template, you can put some link to allow the user to change the language:

  <a href="index.php?lang=en_EN">english</a>
  <a href="index.php?lang=fr_FR">français</a>

Now you can activate the plugin. Inside the configuration file of your application, put in the [plugins] section:

autolocale = autolocale.coord.ini.php

And that's all. Your application supports multiple language at the same time. Now you just have to write properties file for each language.

Automatic detection of the lang

The autolocale plugin allows to detect automatically the lang of the user, by looking at the http headers sent by the browser.

After installing the plugin (see above), set the useDefaultLanguageBrowser variable to "on" in the configuration file of the plugin.

So, when the user arrives on your web site for the first time, the plugin look at http headers to see which language the user use in his browser, and then activate the corresponding language in jelix. (of course, only for language which are listed in availableLanguageCode).