We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
  • Hi there,
    I had a simple plan: I wanted to get two values of a single key from two different lexicons. Why? I wanted to build a switch which reads settings from the lexicon to get different reaction depending on the language.

    I'll try to explain it a little more. Let's say, because it's easy, I wanted to know what "about_msg" (from core / about) would be in French and German.

    Bob (Page 350 in HIS book) and the RTFM (http://rtfm.modx.com/revolution/2.x/developing-in-modx/advanced-development/internationalization) say, that something like this can be done:
    $modx->lexicon->load('es:school:playground');
    $modx->lexicon('school.basketball');

    They said, that "This would load the Spanish version of the 'playground' Topic for the 'school' Namespace. Fun, huh?". Actually, no, it is no fun. Lets see why.
    For my example it would be this code (the "echo" is just for easier testing):
    $modx->lexicon->load('fr:core:about');
    echo $modx->lexicon('about_msg');

    Yeah, one CAN do that (no error message) but it does NOT work as planned. ;-)
    This thing here IS working:
    $modx->lexicon->load('core:about');
    echo $modx->lexicon('about_msg');

    But I wanted to specify a language! They said I could! But the output I get is a result of the current cultureKey setting. Damn. ;-)
    So, I set the culture key manually (Thank you, @WimHauben) which looked like this:
    $modx->setOption('cultureKey', 'fr');
    $modx->lexicon->load('core:about');
    echo $modx->lexicon('about_msg');

    OK, THAT worked well. Problem solved!?

    But now I am asking myself why I can load a lexicon in a specific language. Why did Bob and RTFM say so? What am I missing?

    And another question: is it OK so change the cultureKey in a snippet when I only want to get a certain value from a certain lexicon? Do I REALLY have to do it this way? Isn't there a less risky way? I mean, changing the cultureKey for a simple "gimme that setting" task seems a little bit, well, unconventional. Right?

    Or can someone explain how they ment it and how I can change my code?
      MINDEFFECTS – DESIGN for PRINT, WEB and MEDIA
      http://twitter.com/mindeffects · http://www.facebook.com/mindeffects · http://www.youtube.com/mindeffects/ · skype://mindeffects_oliver
      • 21739
      • 49 Posts
      Perhaps you can pass the desired lexicon key like so? Can't seem to find any info about it...
      $modx->lexicon('about_msg', 'fr');
      • Quote from: nondotzero at Mar 27, 2014, 08:30 PM

        $modx->lexicon('about_msg', 'fr');
        Thanks! Good guess, but: Nope. Does not work. 'fr' is ignored. :-(
          MINDEFFECTS – DESIGN for PRINT, WEB and MEDIA
          http://twitter.com/mindeffects · http://www.facebook.com/mindeffects · http://www.youtube.com/mindeffects/ · skype://mindeffects_oliver
          • 3749
          • 24,544 Posts
          Beats me. wink

          Assuming that the snippet is called uncached and that the language string actually exists in each language, it really sounds like a bug.

          As a workaround, you might try something like this rather than a snippet:

          [[%about_msg? &language=`fr` &namespace=`core` &topic=`about`]]


            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
          • Quote from: BobRay at Mar 28, 2014, 03:16 AM

            Assuming that the snippet is called uncached and that the language string actually exists in each language, it really sounds like a bug.
            Thanks for you reply.
            Yep, uncached and the language string exists.
            Quote from: BobRay at Mar 28, 2014, 03:16 AM
            As a workaround, you might try something like this rather than a snippet:
            [[%about_msg? &language=`fr` &namespace=`core` &topic=`about`]]

            :-) No, no, this is where I came from, the easy way. Wanted to do it like a real coder: by coding. ;-)

            The whole thing is about a "language redirector" I wrote. I evaluate $_SERVER['HTTP_ACCEPT_LANGUAGE'] and then redirect the user to the according language startpage, whose ID is stored in the lexicon. Storing such things in the lexicon might by "my style" because I don't want to use a context. (Note: Context are, in my world, only used for different domains/subdomains, but that is a different story.) Everything related to a language goes into the lexicon and comes from there. Need another language? Copy the lexicon file, translate, done. Superfast (Try this with context settings! :-( )
            OK, here we go with my little non-coder-code which lives in a snippet that is called by the "site_start" resource:
            <?php
            $langBrowser = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
            $posDE = strpos($langBrowser,'de');
            if ($posDE === false) $posDE=9999;
            
            $posEN = strpos($langBrowser,'en');
            if ($posEN === false) $posEN=9999;
            
            if ($posDE < $posEN) {
                $modx->setOption('cultureKey', 'de');
            } else {
                $modx->setOption('cultureKey', 'en');
            }
            
            $modx->lexicon->load('mynamespace:default');
            $id = $modx->lexicon('start.id');
            $url = $modx->makeUrl($id);
            $modx->sendRedirect($url);

            I just want to know which language to serve if someone entery by the front door. On a subpage I evaluate the start of the URL path, like "de/home.html/, and know "where" we are (here: in the "de" branch". There might be better ways, but I wanted it just that way. ;-)

            Now, Bob, you know why I didn't use a lexicon-tag and a header redirect. And "$modx->lexicon->load('en:core:about')" seems to be bugged. Hello GitHub, I'll visit you next.
              MINDEFFECTS – DESIGN for PRINT, WEB and MEDIA
              http://twitter.com/mindeffects · http://www.facebook.com/mindeffects · http://www.youtube.com/mindeffects/ · skype://mindeffects_oliver
              • 4172
              • 5,888 Posts
              did you have look into how migxMultiLang handles this?
                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!
                • 3749
                • 24,544 Posts
                Looking at the modLexicon class code, I don't see any reason why what you're doing wouldn't work.

                Just a thought: If you have changed any lexicon strings in Lexicon Management in the Manager, those would override anything in the lexicon files.


                You might also try calling this between the lexicon() calls:

                $cm = $modx->getCacheManager();
                $cm->refresh();


                It shouldn't make any difference, but if it does it might tell us something.
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 2168
                  • 9 Posts
                  I've encountered similar frustrations with lexicons in scripts. For my purposes, I'm using them within a Plugin that fires when a user is added to a specific usergroup (and sends them an email). Although I can easily add standard MODX lexicon tags to supplement my chunks (and pass those chunks a language variable), the one stumbling block was setting the mail subject line with a lexicon entry, based on the user's preferred language.

                  I ran into the same issue as mindeffects that alleged code would work:
                  $modx->lexicon->load('es:school:playground');
                  $modx->lexicon('school.basketball');
                  

                  I created a test Snippet (because adding and removing myself from usergroups was getting tedious, as was waiting for the resulting email), dropped it onto a site page, and found that I too could fix that issue by setting the cultureKey ahead of the lexicon->load call.
                  // Extra lexicon strings were set via the manager in the Login namespace
                  // $lang was set by reading a user's extended profile and getting their preferred language
                  
                  $modx->setOption('cultureKey', $lang);
                  $modx->lexicon->load('login:register');
                  $subject = $modx->lexicon('register.membership_approved');
                  
                  return $subject; // for testing purposes
                  

                  The above returned the correctly translated string to my site page.

                  So I added the extra code to my Plugin, added/removed myself from the group, and received my email with the subject line as the raw lexicon key. So the code worked within a Snippet, but not a Plugin.

                  I tried BobRay's suggestion of refreshing the cache between lexicon calls, but that didn't work. However, it gave me an idea to try calling my test Snippet on the site page uncached. When I did that, the Snippet returned the raw lexicon key. Call it cached, I get the translated string.

                  Now I don't think you can run a Plugin cached (and rightfully so), so I started throwing different things at my incached test Snippet—and here's what worked:
                  $modx->setOption('cultureKey', $lang);
                  $modx->lexicon->load($lang.':login:register');
                  $subject = $modx->lexicon('register.membership_approved');
                  

                  The only way it would work (for both the uncached Snippet and Plugin) was to set both the cultureKey AND load the lexicon in the manner described in the RTFM.

                  Hope my trial and error saves someone else some time.
                    • 3749
                    • 24,544 Posts
                    Thanks for the information. That really shouldn't be necessary. I see someone filed a bug on it a while back: https://github.com/modxcms/revolution/issues/11240.

                    Looking at the modLexicon class code, I don't see how the specified language could be ignored, though obviously it is.

                    Are you running 2.4.0?
                      Did I help you? Buy me a beer
                      Get my Book: MODX:The Official Guide
                      MODX info for everyone: http://bobsguides.com/modx.html
                      My MODX Extras
                      Bob's Guides is now hosted at A2 MODX Hosting
                      • 2168
                      • 9 Posts
                      Yes, running 2.4.0, but will be shortly upgrading to 2.4.1 (MODX Cloud makes it so easy).