Difference between revisions of "Multilingual Support"

From GeeklogWiki
Jump to: navigation, search
(added pointer to a feature request)
(added section on switching locale settings)
Line 113: Line 113:
 
* COM_getLanguageId returns the shortcut of the current user's language
 
* COM_getLanguageId returns the shortcut of the current user's language
 
* COM_getLanguage returns the full name of the current user's language, i.e. the name of the Geeklog language file (without the .php extension)
 
* COM_getLanguage returns the full name of the current user's language, i.e. the name of the Geeklog language file (without the .php extension)
 +
 +
 +
== Switching locale settings ==
 +
 +
Switching the language will often also require different formatting of the date, time, and other locale settings. For this, you can define alternative settings for each language in your site's config.php.
 +
 +
For example, the default date formatting in Geeklog's config.php is
 +
<pre>$_CONF['date'] = '%A, %B %d %Y @ %I:%M %p %Z';</pre>
 +
which, amongst other things, includes a time format using am/pm. If your site switches between, say, English and German, then your typical German visitor will expect the time to use a 24-hour format, e.g.
 +
<pre>$_CONF['date'] = '%A, %d. %B %Y, %R Uhr';</pre>
 +
 +
If you're using the ISO abbreviation 'de' for German, then you could have the following in your site's config.php:
 +
<pre>$_CONF['date'] = '%A, %B %d %Y @ %I:%M %p %Z';
 +
$_CONF['date_de'] = '%A, %d. %B %Y, %R Uhr';</pre>
 +
With these two lines, Geeklog would use the 'date_de' formatting when displaying content in German, and the 'date' formatting for all the other languages.
 +
 +
Actually, for this to work properly, you will also have to set <code>$_CONF['locale']</code> and <code>$_CONF['locale_de']</code> accordingly, since some of the date formatting (localized day and month names) requires the correct locale to be set:
 +
<pre>$_CONF['locale'] = 'en_GB';
 +
$_CONF['locale_de'] = 'de_DE';</pre>
 +
 +
You can switch all of the following [http://www.geeklog.net/docs/config.html#locale locale settings] as described above:
 +
* <code>$_CONF['locale']</code>
 +
* <code>$_CONF['date']</code>
 +
* <code>$_CONF['daytime']</code>
 +
* <code>$_CONF['shortdate']</code>
 +
* <code>$_CONF['dateonly']</code>
 +
* <code>$_CONF['timeonly']</code>
 +
* <code>$_CONF['week_start']</code>
 +
* <code>$_CONF['hour_mode']</code>
 +
* <code>$_CONF['thousand_separator']</code>
 +
* <code>$_CONF['decimal_separator']</code>
  
  

Revision as of 22:45, 1 January 2007

Background

The Geeklog language files have been translated into more than 25 languages - but that only means that you can have the user interface in one of those languages. For the actual site content (articles, static pages, ...), there was no support for multiple languages, which means that you either had to have everything in one language only or you ended up with all the different language versions of, e.g. an article, being displayed to anyone.

Euan McKay then came up with a first multi-language hack, which was later built upon and generalized by LWC.

The multi-language support in Geeklog (as of version 1.4.1) is based on this earlier work by Euan and LWC.


How it works

The basic idea behind the multi-language support is to encode the language of an object into its ID. For example, for a story to encode it into the story ID, like so:

http://www.example.com/article.php/introduction_en -- English version
http://www.example.com/article.php/introduction_de -- German version

Now there is a way to identify the language of an object (article, topic, static page, ...) and it can be displayed (or not), based on the user's language preferences. It's also possible then to switch between the various languages in which an object exists in the database.


Setting it up

In config.php, there is a new section to enable multi-language support and to define the list of supported languages:

// Multi-language support
// (note that this section is commented out - remove the '/*' and '*/' lines
//  below to activate it and make sure you understand what it does)
/*

// IMPORTANT!
// 1) Both the $_CONF['language_files'] and the $_CONF['languages'] arrays
//    (see below) must have the same number of elements.
// 2) The shortcuts used must be the same in both arrays.
// 3) All shortcuts must have the same length, e.g. 2 characters.

// The shortcuts are to be used in IDs of objects that are multi-language
// aware, e.g. /article.php/introduction_en and /article.php/introduction_de
// for the English and German version of an introductory article.

// Supported languages
// Maps a shortcut to a Geeklog language file (without the '.php' extension)
$_CONF['language_files'] = array (
    'en' => 'english',
    'de' => 'german_formal'
);

// Display names of supported languages
// Maps the same shortcuts as above to a language name. The language names
// are used to let users switch languages, e.g. in a drop-down menu.
$_CONF['languages'] = array (
    'en' => 'English',
    'de' => 'Deutsch'
);

*/

To enable multi-language support, the two arrays $_CONF['language_files'] and $_CONF['languages'] have to be defined. In the default config.php, they are commented out and, therefore, not defined.


The shortcuts

For each of the languages you intend to support, you will have to define a shortcut that will then be used in the IDs of the multi-language objects, as explained above.

You can freely define these shortcuts, but it would make sense to set them in some relation to the language which they represent. From Geeklog's point of view, though, it doesn't matter whether the English language is represented by a shortcut 'en' or by 'peter'.

Please note:

  • All the shortcuts in both of the arrays have to be of the same length.
  • The shortcut must be appended to the end of an object's ID and it must be preceded by an underscore '_' character.
  • It's recommended that you use a language's ISO abbreviation ('en' for English, 'de' for German, etc.), either with or without the country appendix ('en-US'), as Geeklog will also try to determine a user's preferred language from their browser setting.


The language files

The $_CONF['language_files'] array defines which language files should represent which language. Note that Geeklog also uses the language file name for a user's language setting (in their preferences).

It's recommended that you remove all the other language files, i.e. those for which you do not intend to have content in that particular language on your site.

Note: Be careful when mixing languages that use different character sets (e.g. Russian and Japanese). You may want to switch to the UTF-8 versions of all language files for such a setup.


The language names

The $_CONF['languages'] array defines a set of display names for the supported languages. These names are used to let the user switch between the supported languages, e.g. from a drop-down menu.

Most of the time, you'll want to use the native names of the languages, e.g. "Deutsch" instead of "German", but that's only a convention.


Switching languages

Registered users can always switch their preferred language by selecting another language in their preferences.

To make things more convenient (and also allow anonymous users to switch the language), you can put a PHP block on your site. Geeklog provides a function phpblock_switch_language that will display a drop-down menu of all available languages (if you only have two languages defined, it will display a simple link to the other language instead).

This function can also be called from the header.thtml template file of your theme, so that you can put it into your site's menu:

<?php print phpblock_switch_language(); ?>

Technically, switching the language will set a cookie (with the selected language) and also update a user's language preference, if they're registered with the site.


Detecting the language

When a user comes to a multi-language enabled site, Geeklog will check for the user's preference setting first (if it's a registered user), then for the language cookie, and if that couldn't be found, it tries to get the language from the browser's 'Accept-Language' header (which only works if you chose to use the ISO shortcuts, as explained above). If all else fails, content will be presented in the site's default language, i.e. $_CONF['language'].


Supporting multiple languages

Developers of plugins and other add-ons don't have to do much to support multiple languages. Mainly, the objects under your plugin's control will have to have an editable, non-numerical ID (like Geeklog's stories have), so that the language shortcut can be appended to the ID.

If you have a list of objects under your plugin's control and only want to show the objects in the current language, you can use the COM_getLangSQL() function when building your SQL request. It will provide the part of an SQL request to only return the objects in the current language (see the function's description in lib-common.php for details).

COM_getLangSQL() will return an empty string when multi-language support is disabled, so you don't need to check for that yourself.

Most of the time, that should be all that you need to know about supporting multiple languages in a plugin. In some scenarios, the following functions may also come in handy:

  • COM_getLanguageId returns the shortcut of the current user's language
  • COM_getLanguage returns the full name of the current user's language, i.e. the name of the Geeklog language file (without the .php extension)


Switching locale settings

Switching the language will often also require different formatting of the date, time, and other locale settings. For this, you can define alternative settings for each language in your site's config.php.

For example, the default date formatting in Geeklog's config.php is

$_CONF['date'] = '%A, %B %d %Y @ %I:%M %p %Z';

which, amongst other things, includes a time format using am/pm. If your site switches between, say, English and German, then your typical German visitor will expect the time to use a 24-hour format, e.g.

$_CONF['date'] = '%A, %d. %B %Y, %R Uhr';

If you're using the ISO abbreviation 'de' for German, then you could have the following in your site's config.php:

$_CONF['date'] = '%A, %B %d %Y @ %I:%M %p %Z';
$_CONF['date_de'] = '%A, %d. %B %Y, %R Uhr';

With these two lines, Geeklog would use the 'date_de' formatting when displaying content in German, and the 'date' formatting for all the other languages.

Actually, for this to work properly, you will also have to set $_CONF['locale'] and $_CONF['locale_de'] accordingly, since some of the date formatting (localized day and month names) requires the correct locale to be set:

$_CONF['locale'] = 'en_GB';
$_CONF['locale_de'] = 'de_DE';

You can switch all of the following locale settings as described above:

  • $_CONF['locale']
  • $_CONF['date']
  • $_CONF['daytime']
  • $_CONF['shortdate']
  • $_CONF['dateonly']
  • $_CONF['timeonly']
  • $_CONF['week_start']
  • $_CONF['hour_mode']
  • $_CONF['thousand_separator']
  • $_CONF['decimal_separator']


Notes and ideas

  • To make things nicer for the user, the language could be hidden from the ID when editing objects. Instead, the user could be presented with a drop-down menu of the available languages. The shortcut could then be silently added to the ID when the object is saved.
  • Feature Request: Make it easier to make a copy of an article for translation.