On March 26, 2019 we launched new MODX Forums. Please join us at the new MODX Community Forums.
Subscribe: RSS
  • Hi

    I’m new to modx Revolution, and I’m currently trying to figure out how to make a multi-lingual site.

    I’ve found how to insert localized strings in chunks using lexicons, this part works fine. But now I’d like to go further and provide a way to switch the whole site to another language. As far as I’ve understood, I need to use a different context per language; each context will have its own translated resource tree. But then how do I provide a link to switch between the contexts I created? How to find the URL of the page corresponding to the current one in the new language? The documentation doesn’t seem to explain this part yet.

    Thanks for your help.
    • Quote from: LaurentGom at Aug 09, 2009, 08:04 PM

      But then how do I provide a link to switch between the contexts I created? How to find the URL of the page corresponding to the current one in the new language? The documentation doesn’t seem to explain this part yet.
      This will be up to developers to determine, based on their needs. For instance, are you going to provide subdomains for each language, or is it going to just be subfolders used to organize the tree? These kinds of questions need to be answered in order to determine how you are going to "switch" contexts, or even if you need contexts (using subfolders wouldn’t require having separate contexts, though you may want to isolate the content and settings this way anyway). You could use a plugin to detect the subdomain from the http_host setting, or a particular subfolder in the requested URL, and switch to a particular context based on that information. Or you could create physical subfolders with custom index.php files in each one to prevent loading the main ’web’ context on each request and then switching (i.e. directly initialize a particular context).
      • I’ll use a separate subfolder for each language. Something like this:
        http://www.mysite.com/en/home.html
        http://www.mysite.com/fr/accueil.html

        (BTW, is there a way to remove the ".html" suffix? I changed the corresponding system property with an empty string, but it doesn’t seem to have any effect)

        You could use a plugin to detect the subdomain from the http_host setting, or a particular subfolder in the requested URL, and switch to a particular context based on that information. Or you could create physical subfolders with custom index.php files in each one to prevent loading the main ’web’ context on each request and then switching (i.e. directly initialize a particular context).
        Can you elaborate on that? Which solution is the best?
        And what about finding the corresponding translated node/URL ?
        • Quote from: LaurentGom at Aug 10, 2009, 06:21 AM

          (BTW, is there a way to remove the ".html" suffix? I changed the corresponding system property with an empty string, but it doesn’t seem to have any effect)
          This is managed by Content Type in Revolution. The suffix and prefix from Evo are no longer applicable and are retained there only for the interest of migrations.

          Quote from: LaurentGom at Aug 10, 2009, 06:21 AM

          You could use a plugin to detect the subdomain from the http_host setting, or a particular subfolder in the requested URL, and switch to a particular context based on that information. Or you could create physical subfolders with custom index.php files in each one to prevent loading the main ’web’ context on each request and then switching (i.e. directly initialize a particular context).
          Can you elaborate on that? Which solution is the best?
          And what about finding the corresponding translated node/URL ?
          Which is best really depends on your hosting situation. For instance, if you have full control of a dedicated server or VPS, and need more scalability for a large volume of traffic, then using custom index.php’s that directly invoke a specific context will be your best option. This customization is as simple as copying the index.php in the root directory to an fr/ folder and changing the call to $modx->initialize(’web’) to $modx->initialize(’fr’), though you will also need to copy the config.core.php file and make sure the values are correct for the new location. A quicker and less complex solution would be to have a plugin which detects the requested subfolder and switches to the appropriate context from the main ’web’ context.

          As for linking related nodes across translations, there is nothing built-in for this in 2.0. Again, this depends on your needs and I expect that several solutions to this will materialize as developers implement similar solutions. This could be as simple as creating a TV on the main page which has a comma-delimited list of translated nodes (and possibly a second TV on the translations that point back to main node), or as complex as creating a custom table to map the relations explicitly.

          Once we get to our initial RC releases of Revolution, I’m sure we will be providing sample solutions for these issues. For the time being, your exploration of the subject is a pioneering effort, though greatly appreciated.
          • This is managed by Content Type in Revolution. The suffix and prefix from Evo are no longer applicable and are retained there only for the interest of migrations.
            Ok, I see.

            Which is best really depends on your hosting situation. For instance, if you have full control of a dedicated server or VPS, and need more scalability for a large volume of traffic, then using custom index.php’s that directly invoke a specific context will be your best option. This customization is as simple as copying the index.php in the root directory to an fr/ folder and changing the call to $modx->initialize(’web’) to $modx->initialize(’fr’), though you will also need to copy the config.core.php file and make sure the values are correct for the new location.
            I’ll try this solution, as I don’t know how to write a plugin yet. If I understand correctly, I’ll also have to change my rewrite rules in .htaccess to map the virtual language folders to the physical ones?

            As for linking related nodes across translations, there is nothing built-in for this in 2.0. Again, this depends on your needs and I expect that several solutions to this will materialize as developers implement similar solutions. This could be as simple as creating a TV on the main page which has a comma-delimited list of translated nodes (and possibly a second TV on the translations that point back to main node), or as complex as creating a custom table to map the relations explicitly.

            Once we get to our initial RC releases of Revolution, I’m sure we will be providing sample solutions for these issues. For the time being, your exploration of the subject is a pioneering effort, though greatly appreciated.
            Thanks for the hints. I’ll post back here once I’ve made all this stuff work smiley
            • Quote from: LaurentGom at Aug 10, 2009, 04:00 PM

              I’ll try this solution, as I don’t know how to write a plugin yet. If I understand correctly, I’ll also have to change my rewrite rules in .htaccess to map the virtual language folders to the physical ones?
              Good point; actually, it may be better to leave the rewrite rules alone for now. We should focus on solving the problem, and then optimizing in this case. You need a plugin to detect the first segment of the requested URL, which will be rewritten into the $_GET[’q’] variable (though ’q’ is configurable in Revolution via $modx->getOption(’request_param_alias’)) when using friendly_urls with mod_rewrite. A plugin like this might be used to do the context switching, assigned to the OnWebPageInit event:
              <?php
              $lang = 'en';
              $pos = strpos($_GET[$modx->getOption('request_param_alias')], '/');
              if ($pos > 0) {
                  $lang = substr($_GET[$modx->getOption('request_param_alias')], 0, $pos);
              }
              switch ($lang) {
                 case 'fr':
                    $modx->switchContext('fr');
                    break;
                 default:
                    // by default, don't do anything
                    break;
              }
              ?>
              

              [Please note this is not tested; I just threw this together for example purposes]

              But again, if you are just using subfolders, you may not even need to go to the trouble of dividing this into contexts. This is more useful for multi-domain configurations. In your case, just figuring out how to link the translations between folders is all you really need, unless you are going to be serving hundreds/thousands of pages per language.
              • If I don’t use contexts then how do I associate a language/locale to a sub-tree? I still need this for the translated chunks that use lexicons -- at least.
                • Quote from: LaurentGom at Aug 10, 2009, 05:44 PM

                  If I don’t use contexts then how do I associate a language/locale to a sub-tree? I still need this for the translated chunks that use lexicons -- at least.
                  In the same plugin, set the locale; the top-level container in the tree represents the language, so once you detect the top level parent, you know the language. This is no different than in 0.9.x/1.0 (aka Evolution).
                  • I added your plugin and changed the locale using
                    setlocale(LC_ALL, ...)

                    which seems to work fine (if I display the current locale it is "french" under www.mysite.com/fr).

                    However it doesn’t change anything for MODx: lexicons are still in english and $modx->countryKey is "en".
                    What am I missing?