We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 28042 ☆ A M B ☆
    • 24,524 Posts
    Yes. I created the first language (english, in my case ) then copied (this was before the lovely ModX "duplicate" feature; the next one will be sooo much easier!) everything into more folders. Anyone interested can see the site at www.bmptrans.ch. Their original site was just three directories with HTML files. I mostly just copy/pasted the content from their old site; then they sent me all kinds of .doc files with new content. They didn’t have time to update it themselves...oh well, they’re the ones paying for it! I have updated the editor to FCKEditor, with a much cut-down menu. Hopefully they’ll find it easier to be able to paste from their Word documents. <sigh>

    They are also the ones for whom I wrote the DocMan system! It is fully multilanguage as well. The menu at the top is based on a simple list menu snippet called with id=0. It uses an older method I worked out of passing the language ID in the URL, that involved hacking every script and snippet that generates a URL.

    This way is much better, although depending on cookies could be somewhat problematical, I suppose. I’m not going to mess with their site any more; it’s working great for them as it is. But my next one will use the new method.

    Now all I have to do is get them to take the time to give me all the translations that I need for all the langauge files!
      Studying MODX in the desert - http://sottwell.com
      Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
      Join the Slack Community - http://modx.org
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      Modified the "HomeAlone" snippet to hadle a multilanguage site. It gets the $lang variable from the COOKIE, then checks to see if the page ID == $lang. If true, this is the "home" page for that language.

      Every chunk or snippet you want processed by HomeAlone MUST be duplicated, with the $lang (the document ID of that language’s home page) appended to the name: HomeChunk1, HomeChunk43; whatever the language’s home page ID is.

      You call the HomeAlone snippet with the base name of the chunk/snippet: HomeChunk

      The HomeAlone snippet automatically appends the $lang to the base name to include the snippet/chunk for the language the page being processed belongs to.

      This way you can easily edit and translate the snippet/chunk being included to suit its language. For example, the div ID of a chunk could be changed, and the CSS file would be able to use a different background image to suit the language, flags for example.

      // --------------------
      // Snippet: HomeAlone
      // --------------------
      // Version: 0.6a
      // Date: 2004.09.02
      // [email protected]
      //
      // This snippet was designed to show other snippets or chunks
      // that should appear on the home page only, or on all BUT 
      // the home page.
      //
      // Modifed 2004.07.13
      // [email protected]
      // for multilanguage sites
      // use base snippet/chunk name in template
      // you must have a separate snippet/chunk for each language used
      // snippet/chunk name iteself uses basename + ID of main language homepage
      // homepage check checks to see if page ID = $lang
      // snippet/chunk names passed in call parameter
      // have $lang appended while being loaded into array
      // eg HomeBanner is used in call parameter
      // if the $lang of the page being loaded is 1, the snippet/chunk name
      // will be modified to HomeBanner1
      
      
      // Configuration Settings
      
         // $HA_sHome and $HA_sNotHome [ set in snippet call parameter ]
         // These variables are pipe separated strings of snippet names to run
         // on the home page (in the case of $HA_sHome) or to run  on all BUT the
         // home page (in the case of $HA_sNotHome). 
         // Call the snippet like this:
         // [[HomeAlone?HA_sHome=FirstSn|SecondSn&HA_sNotHome=third|fourth]]
         
         // $HA_cHome and $HA_cNotHome
         // These work exactly the same way but for chunks. You can use 1, 2, 3 or all 4 
         // parameters in a single call if you wish, but this will tend to get confusing:
         // [[HomeAlone?HA_cHome=snippet1&HA_cNotHome=snippet2&HA_cHome=chunk1&HA_cNotHome=chunk2]]
      
         // Snippets will be processed first then chunks.
      // for multilanguage sites, get the $lang value
      // or use site_start
      $lang = isset($_COOKIE['Language']) ? $_COOKIE['Language'] : $modx->config['site_start'];
      
      // something has to be set for this to run
      if (isset($HA_sHome) || isset($HA_sNotHome) || isset($HA_cHome) || isset($HA_cNotHome)){ 
        // decide if this is the home page - modified for multilang
        $atHome = ($modx->documentIdentifier == $lang) ? true : false ;
        // get the snippet/chunk for that language
        
        // find snippets
        $homeSnippets = isset($HA_sHome)? explode("|",$HA_sHome): '';
        $notHomeSnippets = isset($HA_sNotHome)? explode("|",$HA_sNotHome): '';  
        // initialize output variable
        $output = '';
        // 
        if ($atHome){
          if ($homeSnippets){
            foreach($homeSnippets as $snippetName){
              $output .= '[['.$snippetName.$lang.']]'; // add $lang to name
            }
          }
        } else { // other than home page
          if ($notHomeSnippets){
            foreach($notHomeSnippets as $snippetName){
           $output .= '[['.$snippetName.$lang.']]'; // add $lang to name
            }
          }
        }
      
        // find chunks
        $homeChunks = isset($HA_cHome)? explode("|",$HA_cHome): '';
        $notHomeChunks = isset($HA_cNotHome)? explode("|",$HA_cNotHome): '';  
        // decide if this is the home page
        if ($atHome){
          if ($homeChunks){
            foreach($homeChunks as $chunkName){
              $output .= '{{'.$chunkName.$lang.'}}'; // add $lang to name
            }
          }
        } else { // other than home page
          if ($notHomeChunks){
            foreach($notHomeChunks as $chunkName){
           $output .= '{{'.$chunkName.$lang.'}}'; // add $lang to name
            }
          }
        }
        
        return $output;
      }
      
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 28042 ☆ A M B ☆
        • 24,524 Posts
        I’ve discovered (the hard way!) that the home pages for each language cannot be cached. Apparently the cookie will not be refreshed on changing languages if the homepages are cached, even if the SetLang snippet is called non-cached ([!...!]). At least this was an issue I seemed to run into; YMMV.

        I’ve also found that the [*lang*] TV does not seem to be universally available. No big deal; it’s easy enough to add a one-liner to any snippet or whatever that doesn’t seem to get it:

        $lang = isset($_COOKIE['Language']) ? $_COOKIE['Language'] : $modx->config['site_start'];
        


          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 28042 ☆ A M B ☆
          • 24,524 Posts
          Just noticed that the main menu doesn’t have a "home" page in this system. rolleyes

          Here’s a chunk that can be inserted into the template immediately before calling the menu snippet:

          <ul><li><a href="index.php?id=[*lang*]">Home</a></li></ul>


          Remove the ul and li tags if you’re using a menu snippet that doesn’t create lists.

          This will return the user to the main page for the language of his choice.

          Inserted immediately before a menu snippet, inside the same block-level tags (such as <div>) it will be easy to control its display with the same CSS used on the snippet’s menu items. You would have to set the nodiv parameter in ListMenuX to "true", and enclose the whole menu in block-level tags in your template, for example:

          <div id="topmenu" class="wide">
          {{HomeMenuItem}}
          [[ListMenuX?id=[*lang*]&depth=1&nodiv=true]]
          </div> <!-- end top menu -->
            Studying MODX in the desert - http://sottwell.com
            Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
            Join the Slack Community - http://modx.org
            • 28042 ☆ A M B ☆
            • 24,524 Posts
            Found a nasty bug in the SetLangCookie snippet. The site works fine, but "view source" or validating with the W3C tool would loop the redirect, since those don’t set the cookie. Here’s the corrected snippet:

            // SetLangCookie snippet for ModX
            // set cookie with language ID
            // 08-28-2005
            // [email protected]
            
            $lang=$modx->documentIdentifier;
            setcookie("Language",$lang,time()+604800, "/", "", 0);
            
            if(isset($_COOKIE['Language']) && $_COOKIE['Language'] != $lang) {
                $url = $modx->makeURL($lang);
                $modx->sendRedirect($url);
            }
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              I decided that I don’t like that kludge of redirecting to sync the cookie with the new language choice, so I reworked the TV and the snippet.

              Drop this snippet into each of your main language home page documents:

              // SetLangCookie snippet for ModX
              // set cookie with language ID
              // 08-28-2005
              // [email protected]
              
              $lang=$modx->documentIdentifier;
              setcookie("Language",$lang,time()+604800, "/", "", 0);


              That sets the cookie.

              Then use this TV wherever you need the $lang variable to be set, such as in setting the ID for a menu snippet:

              Default value:
              @EVAL
              if($modx->documentObject['parent'] == 0) {
              $lang=$modx->documentIdentifier;
              }
              else
               if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
              else {$lang=$modx->config['site_start'];}
              return $lang;


              This first checks to see if the document is one of the main root documents (parent=0; where your language home pages/folders are); if so, it uses that document’s id for the $lang variable. If not, it gets the $lang variable from the cookie; if that’s not available, then it uses the default site_start, which should be your default language’s home page. So even if the user has cookies disabled, he’ll still get the whole site in the default language, he just won’t be able to change languages.

              The first check is necessary because the $lang variable is grabbed from the (old) cookie before the new cookie is set, causing the menus to be one step behind the user’s new language selection. This way, if the page is a new language selection, its ID is used, instead of the old cookie value. The cookie is now up-to-date, so further menu selections will be from the correct language folder.
                Studying MODX in the desert - http://sottwell.com
                Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                Join the Slack Community - http://modx.org
                • 4673
                • 577 Posts
                Susan,

                Is this something that could worked into the core?

                I’d really like to see modx multilingual out of the box without having to revert to work arounds.
                  Tangent-Warrior smiley
                  • 28042 ☆ A M B ☆
                  • 24,524 Posts
                  I wouldn’t call this a "workaround" any more than the news snippet is a "workaround". It’s just a very simple way of creating a mulitlanguage site, mostly taking advantage of the document tree system.

                  I chose the cookie method over another method I used before that carried the $lang variable in the URL query string and the SESSION because that method required modifying a number of existing snippets and the core parsing engine. Plus, sessions can time out, losing the user’s language choice.

                  This method only requires one snippet, to set the cookie, one TV to get the value from the cookie (which you would need anyway, to get the value from wherever you are storing it, and feed it to whatever needs it), and one chunk to add a Home link to each language’s main menu (which you would also need in any case). It works seamlessly with all menu snippets, the web login snippet, and anything else you might want to have.
                    Studying MODX in the desert - http://sottwell.com
                    Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                    Join the Slack Community - http://modx.org
                    • 4673
                    • 577 Posts
                    coool!

                    sorry about the bad usage of "work around" but in a sense I still think that multi-lingual support should really be at a base level rather than at a snippet/plugin level. PostNuke did a pretty good job of it especially with their use of boxes based on which language the user was using.

                      Tangent-Warrior smiley
                      • 19889
                      • 616 Posts
                      Quote from: sottwell at Sep 12, 2005, 05:53 PM

                      I decided that I don’t like that kludge of redirecting to sync the cookie with the new language choice, so I reworked the TV and the snippet.

                      Drop this snippet into each of your main language home page documents:

                      // SetLangCookie snippet for ModX
                      // set cookie with language ID
                      // 08-28-2005
                      // [email protected]
                      
                      $lang=$modx->documentIdentifier;
                      setcookie("Language",$lang,time()+604800, "/", "", 0);


                      That sets the cookie.

                      Then use this TV wherever you need the $lang variable to be set, such as in setting the ID for a menu snippet:

                      Default value:
                      @EVAL
                      if($modx->documentObject['parent'] == 0) {
                      $lang=$modx->documentIdentifier;
                      }
                      else
                       if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
                      else {$lang=$modx->config['site_start'];}
                      return $lang;


                      This first checks to see if the document is one of the main root documents (parent=0; where your language home pages/folders are); if so, it uses that document’s id for the $lang variable.  If not, it gets the $lang variable from the cookie; if that’s not available, then it uses the default site_start, which should be your default language’s home page.  So even if the user has cookies disabled, he’ll still get the whole site in the default language, he just won’t be able to change languages.

                      The first check is necessary because the $lang variable is grabbed from the (old) cookie before the new cookie is set, causing the menus to be one step behind the user’s new language selection.  This way, if the page is a new language selection, its ID is used, instead of the old cookie value.  The cookie is now up-to-date, so further menu selections will be from the correct language folder.


                      I might be stupid but I’m not sure how to set this stuff up - I’m kind of new to modx, maybe that’s why. I created a snippet with the setcookie stuff above, but where do I go from here? Do I have to put this
                      @EVAL
                      if($modx->documentObject['parent'] == 0) {
                      $lang=$modx->documentIdentifier;
                      }
                      else
                       if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
                      else {$lang=$modx->config['site_start'];}
                      return $lang;

                      just into the template or how do I use it.

                      I would very much appreciate if somebody could line out some detailled instructions.

                      thank you in advance for your input.