Blog Back to all posts View all authors

MODx multi-language web app using native MODx contexts and Babel

by Yaroslav Ushak
August 31. 2018

Modx Multilanguage Web App - How To Make it?

Welcome to the express course on MODx Multilanguage App creation. Our target is to make it multi-language and catchable without using complicated techniques. We also don’t want to mess with plugins that don’t work as they should. Every web developer knows that bad plugin brings a content manager crying “It doesn’t work, help me!”.

MODx Multilanguage web app - A 5 Steps Guide

First of all, let’s define the necessary contexts, assuming that we need Russian, English and Polish. For each language, we need to create a separate context which handles routing for us and separated resource menu in the manager panel:

1. Define context in manager and its keys and settings specific to the context.

You can find context settings under Settings -> Contexts. Here we define it just like on the example below.


Modx Multilanguage, Context Settings, MODx Language App, Web App, Web Developmnet, Babel -


MODx multilanguage, MODx Plugin, Multi-Language Website, Controller Settings, System Settings -


2. Initialize the app with a proper language.

At this point, initialization should depend on the preferences of a user agent and set some cookies properties for language switching. For this purposes, I use a snippet in the entry point of the web app by default in MODx which is index.php in the main folder. All you need to do is to change:




function preferedLanguage(array $available_languages, $http_accept_language) {

    $available_languages = array_flip($available_languages);
    $langs = array();
    preg_match_all('~([\w-]+)(?:[^,\d]+([\d.]+))?~',   strtolower($http_accept_language), $matches, PREG_SET_ORDER);
    foreach($matches as $match) {
        list($a, $b) = explode('-', $match[1]) + array('', '');
        $value = isset($match[2]) ? (float) $match[2] : 1.0;
        if(isset($available_languages[$match[1]])) {
            $langs[$match[1]] = $value;
        if(isset($available_languages[$a])) {
            $langs[$a] = $value - 0.1;
    return $langs;

$available_languages = array("en", "pl", "ru");
if(isset($_COOKIE["language"]) && in_array($_COOKIE["language"] ,$available_languages)){
    $selectedLang = $_COOKIE["language"];
    $selectedLang = null;
$modx->startTime= $tstart;

    $langs = prefered_language($available_languages, $_SERVER["HTTP_ACCEPT_LANGUAGE"]);
    $lang = key($langs);
    if($lang === "en" || $selectedLang === "en"){
        $lang = "web";
        setcookie( "language", $lang, strtotime( '+120 days' ) );
        setcookie( "language", $lang, strtotime( '+120 days' ) );
        header('Location: '.MODX_SITE_URL.$lang."/");
    setcookie( "language", "en", strtotime( '+120 days' ) );


3. Create separated folders for each context

They will contain entry point context, htaccess which will send a request to context entry and, if needed, we can add separated configuration which will override the default and place there our file source if it needs to be separated. Here we can copy default htaccess from the main folder and replace it:

RewriteBase /


RewriteBase /kontext_key(ru,pl or en)/

And in entry index.php change:





4. Time for Babel

For chaining resources by translation, I suggest using a plugin for MODx called Babel. Note that this plugin doesn’t make contexts and routing for you by default. It only chains resources by translation for better manipulation from the manager. It also provides us with ready to use snippets which retrieve paths of chained resource and chained resource id. If you install it before creating context, you`ll need to change context properties in plugin settings.

Now you have a possibility to get resource id of translation by default web context resource with this tag:

[[BabelTranslation? &resourceId=`10` &cultureKey=`[[++cultureKey]]`]]

And get links for translation like so:

 [[BabelLinks? &resourceId=`[[*id]]` &activeCls=`active` &tpl=`lang_template_name` &showCurrent=`true`]]

For more info check doc page:

5. One template for all contexts

The last part is to make one template for all contexts with dynamic translations which are provided by default with modx core functionalities. First, create namespace:

MODX Multilanguage, MODx plugin, Babel, Multi-Language, Web App, Web Development, Native MODx Contexts -

Now the path to your translations is assets->lexicon->{lexicon_key} folder files with the name of {topic}.inc.php in which we will store translations like so:

$_lang['translation_name'] = 'Translation string';

and retrieve that translations in templates like so:

[[%translation_name?  &language=`[[++cultureKey]]` &topic=`about`  &namespace=`theme` ]]

That's all from me! With these twaeks, you will gain a fully translated web page divided by context. With full control from file source to configurations.

Enjoy! :)


How To Make DIY MODx Plugin?

contact us

Have an idea ? Let’s talk

Office in Rzeszow
Office in Warsaw


Fill up the form and we will contact you shortly


Company information

Fill up the form and we will contact you shortly.

ServoCode Sp. z o.o.

Jasionka 954E, 36-002 Jasionka, Poland

NIP: 8133719852

REGON: 364182909

KRS: 0000611643

We are using cookies to provide statistics that help us give you the best experience of our site. You can find out more or switch them off if you prefer. However, by continuing to use the site without changing settings, you are agreeing to our use of cookies. Read more