We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 7923
    • 4,213 Posts
    I'm using the Login snippet for my logins. I have different type of users in my application. Some of them have E-mail address as the username and some have plain old username.

    When user logs in with wrong details, Login gives an error "That account could not be located. Check the username and re-type the password to try again." I tracked it down and it's the login_cannot_locate_account from core lexicon under login topic.

    Couple questions:

    1. Why Login snippet uses core lexicon entries? I'd like to translate that error message for the site, eg. web context, but not for the manager, eg. mgr context. Is that possible?

    2. Is it possible to define what lexicon a snippet should use when you call a snippet. I'd like to display the above error message in some areas of my app as "Invalid e-mail address and/or password" and in other areas "Invalid username and/or password". Can I somehow have multiple lexicons for a snippet and then tell it what to use and when?

    This question has been answered by doze. See the first response.



      "He can have a lollipop any time he wants to. That's what it means to be a programmer."
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      You can specify the lexicon for a context in its context settings; this will override the default system settings. Just make sure that you do have an entry for the strings in your context's lexicon 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
        • 3749
        • 24,544 Posts
        In your own snippets, the lexicon used is determined by the most recent $modx->lexicon->load() call. So you can do this:

        <?php
        $modx->lexicon->load('en:mysnippet:default);
        $message = $modx->lexicon('file_not_found'); // sets the English message
        
        $modx->lexicon->load('de:mysnippet:default');
        $message = $modx->lexicon('file_not_found'); // sets the German message


        Every lexicon->load for a topic overwrites the previous lexicon strings for that topic. It's not possible to have more than one set for a given topic in memory at one time.

        The 'mysnippet' part of the load call is the namespace. It assumes that you have created a namespace called 'mysnippet' and set its path to '{core_path}components/mysnippet' and that your default.inc.php lexicon file is at core/components/mysnippet/lexicon/en/default.inc.php.

        A lexicon file is just an associative array of $key and $value pairs, so it's actually quite easy to write your own load() and lexicon() functions. In fact, you don't actually need load, you just include the lexicon file and the simplest version of the lexicon function looks like this:

        function lexicon($key) {
            global $_lang;
            return isset($_lang[$key])? $_lang[$key] : $key;
        }
        

        So, you could actually have more than one language loaded by using a country prefix for the $key part of the array in the lexicon file and having multiple includes. The lexicon function would then look something like this:

        function lexicon($key, $language) {
            global $en_lang, $de_lang;
            if ($language == 'en') {
                return isset($en_lang[$key])
                    ? $en_lang[$key]
                    : $key;
            } elseif ($language == 'de') {
                return isset($de_lang[$key])
                    ? $de_lang[$key]
                    : $key;
            } else {
                return $key;
            }
        }

          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
          • 7923
          • 4,213 Posts
          Sorry, but I didn't quite understand either of you smiley

          I think Susan has a perfectly valid answer to my first question, but I just do not understand it and don't know how to actually do what you say. So:

          1. What steps to take in the manager to translate "login_cannot_locate_account" lexicon key from core lexicon under login topic differently for mgr and web contexts. Where to click and what to do?

          Then I guess Bob has an answer to my second question, but unfortunately I don't understand how to apply this to the Login snippet. So:

          2. How can I tell the Login snippet what lexicon to use when calling the snippet?


            "He can have a lollipop any time he wants to. That's what it means to be a programmer."
            • 3749
            • 24,544 Posts
            Sorry, I looked at the login code, and my answer above isn't much user for your specific situation.

            The login class just calls $this->modx->lexicon->load('login:default') without specifying a language.

            The lexicon class does this check first, and uses that if it's set:

            $defaultLanguage = $this->modx->getOption('cultureKey',null,'en');


            I think that a context setting would override the system setting and a user setting would override both.

            You can create a cultureKey context setting for each context (or a User Setting for each user) that should be used for the Login snippet, though it would also be used elsewhere.


            If you want to have it affect only the Login snippet, another option might be to create different Login Tpl chunks with the language to use specified in the Language tags in the chunk. You could them specify which Tpl chunk to use in the Login snippet tags.

            The tags would look like this:

            [[!%key? &topic=`topicname` &namespace=`namespace_name` &language=`en`]]


            As a last resort, you could modify the login class file, pick a language via a TV or something else, and specify it in the lexicon->load() line. The change would be overwritten when you update the Login package and you'd have to redo it (or duplicate the whole Login section of the package and use that instead of the original).
              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
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              Can't you just create a new setting in the web context for its own lexicon to override the default MODx lexicon?
                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
                • 3749
                • 24,544 Posts
                That's what I was trying to suggest. wink

                A cultureKey Context Setting would do it, but that setting would be used throughout the web context, not just for the Login snippet. I don't know if that would meet the OP's needs or not.
                  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
                  • 7923
                  • 4,213 Posts
                  Hi again.. smiley

                  Have you realized that I have two separate questions in there? I should have created separate topics for them, sorry. Going back again to the questions...

                  ---

                  The first one should be a simple question, I'll repeat again: What steps to take in the manager to translate "login_cannot_locate_account" lexicon key from core lexicon under login topic differently for mgr and web contexts. Where to click and what to do?

                  This is because the Login snippet uses the same lexicon entry as the MODX manager login does and I need different error messages to the front end and back end.

                  ---

                  And now to the second question (about how to specify what lexicon a snippet should use) what seems to be more complex.

                  So if I get it right Bob, you are suggesting that I would go to edit each user that needs different for login_cannot_locate_account lexicon key and set a cultureKey setting for them. What value should it have? "en-custom" or something? Isn't there something like user group settings, because this would mean that I would have to edit over 100 accounts. The users are in same usergroup.

                  Anyhow.. after setting the cultureKey setting, I would create new lexicon entry with login_cannot_locate_account as name, core as namespace, login as topic and en-custom as language? Btw. don't know where to define the available languages. It is a selection list in the create entry dialog and obviously doesn't have my "custom" cultureKey in it.

                  If I would have set all this up successfully, what would happen to everything else in MODX that uses lexicon for that user as I would have only the one login_cannot_locate_account lexicon entry there for the cultureKey that the user is using.

                  But this is just theoretical talk... Seems such a complex way to get certain snippet call to use certain lexicon topic. Of course in the real world, I would just edit the snippet code or duplicate it and loose the updating.


                    "He can have a lollipop any time he wants to. That's what it means to be a programmer."
                    • 3749
                    • 24,544 Posts
                    doze, Here is what I'm suggesting:

                    For the front-end login form, set full language tags in the Tpl chunk and specify that Tpl chunk in the Login snippet tag, unless you want the language to apply to the whole web context, in which case, create a cultureKey Context Setting for the web context. The setting should contain the two-letter code for the language ('en', 'de', 'fr', etc.).


                    For the Manager login form, it's going to use the cultureKey System Setting because it doesn't know who the user is (and why wouldn't you want the manager language to be used in the Manager login form?).

                    User settings aren't going to do any good in either case because no user is logged in yet. User settings will only take effect for snippets that run after the user is logged in. The User Settings would work there, but I think so would a snippet at the top of the template with this code:

                    $modx->setOption('cultureKey', 'en');



                    This snippet (untested) would create the User Settings:

                    <?php
                    /**
                    Create User Settings for a user group
                     */
                    
                        $userGroupName = 'WhateverUserGroupName';
                    
                    $language = 'en'; // or whatever
                    $settingKey = 'cultureKey';
                    
                    $userGroups = $modx->getObject('modUserGroup', array('name' => $userGroupName));
                    
                    if ($userGroups) {
                        $ugms = $userGroups->getMany('UserGroupMembers');
                    } else {
                        return 'No User Groups Found';
                    }
                    
                    if (!empty($ugms)) {
                    
                       foreach ($ugms as $ugm) {
                           $user = $ugm->getOne('user');
                           $id = $user->get('id');
                           $settingName = $settingKey;
                           $setting = $modx->getObject('modUserSetting', array('key' => $settingName,
                               'user' => $id));
                           if (!$setting) {
                               $setting = $modx->newObject('modUserSetting');
                               $setting->set('user', $id);
                               $setting->set('key', $settingKey);
                           }
                           $setting->set('value', $language);
                           $setting->save();
                       }
                    } else {
                        return 'No users in group';
                    }
                    
                    return 'Settings created';










                      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
                      • 28042 ☆ A M B ☆
                      • 24,524 Posts
                      To get a different lexicon key for the "web" context, go to System -> Contexts, and right-click the web context to update it. Create a new context setting, and put in a new cultureKey setting. Take a look at the system cultureKey setting in the "Lexicon and Language" area of the system settings to see what it should look like. This would change it for the entire front-end, however, not just for the one snippet.
                        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