We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 10597
    • 31 Posts
    I am trying to pass a placeholder to a snippet in its parameters inside a template
    Everything works fine when the placeholder has a value. When it does not the parameter has a string length of the placeholder and not empty or zero length like expected. In other programming languages this is an indicator of memory leaks but I am not worried about that in PHP.

    IDK if I am causing this issue so here is the setup.

    Set in plugin at OnHandleRequest
    $modx->setPlaceholders(array(
                        'subdomain' => $location->get('subdomain'),
                        'city' => $location->get('name'),
                        'state' => $location->get('state'),
                        ),'mfm.');

    This is only set when it is a subdomain and not on the main site. If its not a subdomain the mfm.subdomain is not set at all.

    Call to snippet with placeholder as a value
    [[!toggleSnippet? &subdomain=`[[+mfm.subdomain]]`]]


    Code in snippet
    $subdomain =$scriptProperties['subdomain'];
    


    if mfm.subdomain is empty, in the snippet, $subdomain will have a strlen of 18 (the length of "[[+mfm.subdomain]]"). It will not match empty(), strlen = 0, =="", ===" , null or any other methods I normally use to determine if the string is empty.

    Anyone with any insight in to this possible issue?
      Using ModX Revolution
      • 3749
      • 24,544 Posts
      This is only set when it is a subdomain and not on the main site. If its not a subdomain the mfm.subdomain is not set at all.

      This is the cause of your problem. When the placeholder is not set, the placeholder tag is not replaced, so it gets sent to the snippet as is.

      In your plugin, when it's not a subdomain set the placehoder to ''. Then that property will be empty in the snippet in that case.
        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
        • 10597
        • 31 Posts
        Bob, it's not being sent as is. It's an "empty" string but strlen of 18.
        Even though its empty, memory is allocated to it so it won't match as empty or any other method I've tried.

        This is unexpected results, and the only reason I am pointing it out. [ed. note: geeble last edited this post 12 years, 1 month ago.]
          Using ModX Revolution
          • 10597
          • 31 Posts
          The only solution to my problem is to initialize the placeholders as empty and then reset their values in the code when necessary.
          $modx->setPlaceholders(array(
              'subdomain' => "",
              'city' => "",
              'state' => "",
              ),'mfm.');
          


          This solution is only a work around.
            Using ModX Revolution
            • 3749
            • 24,544 Posts
            I strongly suspect that it's not really an empty string. wink It only looks like one when you try to display it in MODX, which removes any unset placeholders as the last step before showing a page.

            I predict that if you write its value to a file or the content of a chunk, you'll see the placeholder tag there.

            Your solution is a correct one, but I think it would be more efficient to use an if statement to find out if it's a subdomain and set the placeholders accordingly just once rather than setting them twice.

            What's happening, in case you're curious, is that the MODX parser makes a number of passes through a page. On each pass, it attempts to replace tags. If a placeholder is set, the corresponding placeholder tag is replaced, but if it's not, the tag is not removed because the placeholder might be set later. Unparsed tags are not removed until the very last pass after all possible attempts to resolve them have failed.

            Tags are parsed from the inside out, so MODX tries to replace the placeholder tag, before parsing the whole snippet tag, but fails because it's not set, so the tag arrives intact in the $scriptProperties array.

              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
              • 10597
              • 31 Posts
              Your solution is a correct one, but I think it would be more efficient to use an if statement to find out if it's a subdomain and set the placeholders accordingly just once rather than setting them twice.

              That is exactly what I was trying to do. These were only to be set where needed. I had to initialize it before my if statements, otherwise this came about.

              What's happening, in case you're curious, is that the MODX parser makes a number of passes through a page. On each pass, it attempts to replace tags. If a placeholder is set, the corresponding placeholder tag is replaced, but if it's not, the tag is not removed because the placeholder might be set later. Unparsed tags are not removed until the very last pass after all possible attempts to resolve them have failed.

              Tags are parsed from the inside out, so MODX tries to replace the placeholder tag, before parsing the whole snippet tag, but fails because it's not set, so the tag arrives intact in the $scriptProperties array.

              This understanding of when they are processed helps greatly.

              So you are right. it is being passed as is. My horrible assumption was it was an empty string since I am echoing debug messages (even though I know I shouldn't) and modx rips them out of the debug message just before sending back the page. So a better in page debug method is coming for my toolset.

              So that brings me to the next question. So since we want to be able to pass an unparsed placeholder in a parameter, I'll need to detect the placeholders and remove them before I can do anything with the data, in this case.
                Using ModX Revolution
                • 3749
                • 24,544 Posts
                To answer your last question first, you have two options. One is to explicitly set the placeholder to '' before the snippet tag executes(e.g., in your plugin) and test for an empty value in the snippet. The other is to test for the placeholder in your snippet:

                if (strpos($subdomain, '[[') !== false) {
                   /* It's the placeholder, act accordingly */
                }


                If you want a belt and suspenders approach, you can do both. wink


                With respect to debugging:

                This will send the value of a string to the error log without disturbing the display:

                $modx->log(modX::LOG_LEVEL_ERROR, $msg);


                I usually prefer intstead to put this function at the top of my code to write the values to a chunk called 'Debug', because you can use QuickEdit on the chunk (right-click on it in the tree) without losing your place in the Manager. The second argument clears the chunk. Without it, all messages are appended to what's there already.

                public function my_debug($message, $clear = false) {
                    /* @var $chunk modChunk */
                    global $modx;
                
                    $chunk = $modx->getObject('modChunk', array('name'=>'Debug'));
                    if (! $chunk) {
                        $chunk = $modx->newObject('modChunk', array('name'=>'Debug'));
                        $chunk->save();
                        $chunk = $modx->getObject('modChunk', array('name'=>'Debug'));
                    }
                    if ($clear) {
                        $content = '';
                    } else {
                        $content = $chunk->getContent();
                    }
                    $content .= $message;
                    $chunk->setContent($content);
                    $chunk->save();
                }
                
                $msg = 'Value of X: ' . $x;
                my_debug($x);
                
                


                You can also set a variable at the top: $doDebug= true, (or send it as a snippet property) and change the code above accordingly.
                  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
                  • 4172
                  • 5,888 Posts
                  I think, you wouldn't have that issue, if you would set the subdomain-placeholder as an empty string, if you are not in a subdomain.

                  $modx->setPlaceholders(array(
                                      'subdomain' => '',
                                      'city' => $location->get('name'),
                                      'state' => $location->get('state'),
                                      ),'mfm.');
                    -------------------------------

                    you can buy me a beer, if you like MIGX

                    http://webcmsolutions.de/migx.html

                    Thanks!