Multiple languages

Manage languages

It is super easy to develop multilingual websites with REDAXO. Located at the System menu, you’ll find a section Languages, with german language predefined.
Add another language by clicking the +, and REDAXO will copy the whole content structure to the target language. The status of all copied articles will be offline—this is default behavior when adding new articles.

Concerning the database, any article will be a self-contained entity in both languages—marked up with the corresponding language ID.
Watch out: all articles and categories are linked across the languages! If you delete an article in one language, it will be deleted in all other languages, too. That’s why you’d better use the offline status to disable articles in a selected language.

<html lang="<?php echo rex_clang::getCurrent()->getCode(); ?>">

The two values of each language—code and name—do not show up in the frontend in the first instance. But you may apply them whenever it seems useful.
The code value for instance is perfectly suited to be used for the HTML language attribute.

We don’t need to stick to only two values. With REDAXO 5, meta fields for languages have been implemented. They allow for language specific features—like we already know from category metas, article metas and media metas.

For instance, they could be used for country flags inside a language switcher, or for setlocale settings in PHP—like this demo site does. Set to “de_DE” for german and “en_EN” for english, showing a date like 22.12.1978 would be formatted according to the locale settings:

// setLocale is a language meta value to support locale settings for any given language
setlocale (LC_ALL, rex_clang::getCurrent()->getValue('clang_setlocale'));

// Display the date according to the locale settings
echo strftime ("%A %e %B %Y", mktime (0, 0, 0, 12, 22, 1978));

// setlocale set to "de_DE":
// Freitag 22 Dezember 1978

// setlocale set to "en_EN":
// Friday 22 December 1978

Depending on the structure of your website, you’ll need some type of “language switcher”.

What should the link target be? Link to the same article in another language? Or better link to the home page?
Do we have article content in all languages? If not, should we let the system fall back to the first language? Or better hide the link from the navigation?

These are just a few questions when planning a language navigation

Two languages

If you’ve got two languages only, you’ll need a very plain navigation in most instances:
A link to the current article in another language will be sufficient.

By the way: in case you sourced out the language navigation to a separate template and want to include it to another template, you can temporarily “save” the $languages variable globally with setProperty:
rex::setProperty('lang_switch', $languages);

Once the language template has been included, you can access the navigation data and show it up:
echo rex::getProperty('lang_switch');

More than two languages

If you need to select from more than two languages, you may use a dropdown element to list all available languages—but only the ones being online. This can be done by “true”:

In this demo, you can see both versions of the language navigation: add another language to show up the extended switcher.

// two languages online -> only show link to other language
foreach (rex_clang::getAll(true) as $lang) {
if (rex_clang::getCurrentId() != $lang->getValue('id')) {
echo '<a href="'.rex_getUrl($this->getValue('article_id'), $lang->getValue('id')).'">'.$lang->getValue('name').'</a>';

// more than two languages online -> show dropdown, current language not clickable
foreach (rex_clang::getAll(true) as $lang) {
if (rex_clang::getCurrentId() == $lang->getValue('id')) {
echo '<li class="dropdown"><a href="#">'.$lang->getValue('name').'</a>';
} else {
echo '<li><a href="'.rex_getUrl($this->getValue('article_id'), $lang->getValue('id')).'">'.$lang->getValue('name').'</a></li>';

Language replacement: such as Sprog

Like we said, alle articles and categories plus their meta values are available in all given languages. However, the media pool does not support this sort of replicated data. This is because a lot of files (like PDF) per se are not multilingual. In case you need multi-language support for the media pool, you can set up custom meta fields.

Despite the notable multi-language support, there may be some content which is difficult to provide within modules, but is supposed to be maintained or translated by CMS authors. Such as forms labels or descriptions, which are included in backend logic and usually shouldn’t be editable for authors. In those cases you can make use of content replacement tools like Sprog addon, which is used for this demo site as well. It provides keys and their related values in all given languages. For instance, if you insert some
{{ search_string }}
it will be replaced with a translation like
Enter search string

The Sprog addon is used on the contact page and for the mobile navigation.


REDAXO CMS is designed to be highly customizable and to control the output in all details. It’s more like a CMS framework, and it perfectly fits with the requirements of web companies developing various websites.

REDAXO 5 rocks!