We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • I have been manually editing all snippets to add a value "&lang=$lang" to all links and link-creating code, such as menu snippets. The $lang variable is determined at the top of every snippet with "$lang = isset($_GET[’lang’] ? $_GET[’lang’] : $modx->config[’site_start’];". The $lang variable is initially determined by the docID of the root folder acting as home page and containing the content pages for that langauge, as selected from a menu generated by a simple list menu snippet using 0 as its base and that does have its links modifed to seed the $lang variable into the system. The language files are also simply named after the same root docID. If it’s the initial visit to the site, or for some reason the query string value gets lost, it defaults to the site_start document ID.

    This works well, but is really not desireable. It seems to me that I could use a plugin on the DocumentPreRender event to add the value to the query string of all links on the page. If I understand this correctly, I can do something like the "filter words" plugin example in the documentation. I would use a regular expression to find all "<a href=.....> and add the query string value at the end of the text before the final ">".

    Am I on the right track here? And can somebody recommend a good site for a crash course on regular expressions? I already tried hacking the core in the rewriteURLs function, and that worked, but it ended up with multiple "lang" fields in the query string, and while the last one was the desired one and it worked, it’s sloppy, and besides, I don’t want to have to have a hacked core for this to work. This way, all I’d need is one modified simple list menu snippet and the plugin for instant multilanguage support. Snippets written to use the feature would simply include their own "snippet/langs/$lang.php" language file as needed.

      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
      • 32963
      • 1,732 Posts
      Hi Susan,

      You’re on the right track. The OnDocumentPreRender event makes it very easy for you to append &lang to every <a> tag inside the document.

      I’m not good at the regx stuff either but you can try this:


      $pattern=’/<a [^>]*href=([\\"\\\’]?)([^>]*)\1[^>]*>/i’;
      preg_match_all($pattern,$x,$ahrefs);
      echo $ahrefs[0][0]." Original "; //orig
      echo $ahrefs[2][0]." Url "; // url

      I borrowed th regx from the PNGAlpha4MSIE plugin smiley
        xWisdom
        www.xwisdomhtml.com
        The fear of the Lord is the beginning of wisdom:
        MODx Co-Founder - Create and do more with less.
        • 16610
        • 634 Posts
        Quote from: sottwell at Jun 16, 2005, 03:30 AM

        And can somebody recommend a good site for a crash course on regular expressions?

        These two are very useful:
        Excellent regular expressions tutorial: http://www.regular-expressions.info/
        Regular expressions library: http://www.regxlib.com/
          Mikko Lammi, Owner at Maagit
          • 4673
          • 577 Posts
          Actually, a bit off topic. But I’ve always been leary of using regex for replacements (ie, in regards to templates and such). How much of hit is regex compared to say caching the language didies and just using a require?
            Tangent-Warrior smiley
          • This isn’t about substituting the text strings, I do use included language files for that. This is about how to pass the $lang variable from page to page via the query string and recover it as needed from the GET array.

            Anyway, I’ve about given up on this idea; not all links on a page are to the local site, and friendly URLs would make it extremely difficult to determine which links were to local pages and which were not. Looks like I’ll be studying up on cookies after all.

            Session works great, and is the easiest, but if the user’s session times out he gets dumped back into the site’s default language. Plus, sessions require fiddling the web login snippet core scripts, and I want this to be a stand-alone solution, a plug-in or a snippet that is easy to use.
              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
            • Ok, here’s my take on a multilanguage site. One snippet, one TV, a folder for language files. That’s it, no hacked core modules or anything nasty.

              Have the language home page documents in the root. i.e. "French", "Italian", "English". These are the only published documents in the root. These documents act as folders for the content for their respective languages. Anything else goes into unpublished folders.

              Have language files to replace placeholders for any generic text, such as login forms, contact forms, etc. These kind of things are what would go in the unpublished folder and get called from all languages. The language files are named after the ID of the language home page, 3.php, 45.php, etc.

              Use this modifed CSS Dropdown Menu snippet to create the language menu and seed the system with the $lang variables:
              // CSSDropMenu
              // simple drop=down menu for ModX
              // usage: [[DropDown?id=x&tt=y]]
              // where x is the parent of the documents to be listed
              // and y is the text you want for the top of the menu
              
              $id = isset($id)?$id:0;
              $toptext = isset($tt)?$tt:"Menu";
              $children = $modx->getActiveChildren($id);
              if($children == false) return;
              $childrenCount = count($children);
              $lang = $modx->documentIdentifier;
              $dm = "";
              
                // a bit of javascript for those whose browsers aren't 
                // CSS2 compliant (and we all know who they are)
              $dm .= "<script type='text/javascript'>
              function showList(thistag) {
                 styleObj = document.getElementById(thistag).style;
                 if (styleObj.display=='none') {styleObj.display = 'block';}
                 else {styleObj.display = 'none';}
              }
              </script>";
              
                // set up the style for the list
              $dm .= "<style type='text/css'>
                #CSSMenu {
                    position:relative;
                    width:100px;
                    z-index:10;
                    background:yellow;
                }
                #CSSMenu ul, #CSSMenu li {list-style:none;}
                #cmTopItem {display:block;cursor:pointer;}
                #cmTopItem ul {display: none;} 
                #cmTopItem:hover ul {display: block;}
              </style>";
              
                // generate the list
              $dm .= "<div id='CSSMenu'>";
              $dm .= "<ul class='cmList' id='cmTopList'>";
              $dm .= "<li id='cmTopItem' class='cmItem' onClick='showList(\"cmList\");'>$toptext";
              $dm .= "<ul class='cmList' id='cmList'";
                // individual items
              for($x=0; $x<$childrenCount; $x++) {
                 $dm .= "<li class='cmList'><a href='[~".$children[$x]['id']."~]&lang=".$children[$x]['id']."'>".$children[$x]['pagetitle']."</a></li>";
              }
              $dm .= "</ul></li></ul></div>";
              
              return $dm;
              


              Use this snippet to set the cookie; put it in each of your language home page documents:
              // SetLangCookie snippet for ModX
              // set cookie with language ID
              
              $lang=$modx->documentIdentifier;
              setcookie("Language",$lang,time()+604800, "/", "", 0);
              


              And finally, this Template Variable to make the $lang variable available anywhere you like, such as the value for the id in the main menu generation snippet, or the logouthomeid in the web login snippet.
              @EVAL
              if(isset($_GET['lang'])) {$lang=$_GET['lang'];}
              else if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
              else {$lang=$modx->config['site_start'];}
              return $lang;
              


              Now, the user stays in the language area he selects, until he selects another.
                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
                • 32963
                • 1,732 Posts

                Very nice susan. Very nice smiley
                  xWisdom
                  www.xwisdomhtml.com
                  The fear of the Lord is the beginning of wisdom:
                  MODx Co-Founder - Create and do more with less.
                • Dumb. Don’t need a modified menu generation snippet to put a lang variable into the URL query string. The snippet in the language home page determines the lang by its document ID. So any simple list menu would work.
                    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
                  • Ok, here’s the final (I do hope! rolleyes ) simplified, actually functional version:

                    snippet SetLang (put in each of the language’s homepage document/folders):

                    // SetLangCookie snippet for ModX
                    // set cookie with language ID
                    
                    $lang=$modx->documentIdentifier;
                    setcookie("Language",$lang,time()+604800, "/", "", 0);
                    if($_COOKIE['Language'] != $lang) {
                        $url = $modx->makeURL($lang);
                        $modx->sendRedirect($url);
                    }
                    


                    And the TV:
                    
                    @EVAL
                     if(isset($_COOKIE['Language'])) {$lang=$_COOKIE['Language'];}
                    else {$lang=$modx->config['site_start'];}
                    return $lang;
                    


                    Put it wherever you need the language variable; for example in the main menu snippet : [[MenuBuilder?id=[*lang*]]]

                    Full instructions attached.
                      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
                    • Thanks for a great and elegant solution Susan!

                      Just a note for those that might not be aware, using this method requires duplicating the "language version(s)" of your site into a seperate folder, with each version being manually translated into the appropriate language(s). Probably the best way to procede is to build your site in your native language in a folder, then duplicate the folder and rename to the appropriate language(s) then start translating. Is that has what works best in your exprience, Susan?
                        Ryan Thrash, MODX Co-Founder
                        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me