We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 9207 ☆ A M B ☆
    • 2,475 Posts
    I have a Snippet something like this:
    [!Snippet?&param=`<a href="[+ph+]">[+ph+]</a>`!]


    but I’ve discovered that MODx doesn’t like the parameters to be that way... is there a list somewhere that shows what valid parameter rules/characters are?
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      ?, &, =

      It’s logical...those are delimiters for the parameters themselves. There are two ways to deal with this. You can use different characters in the parameter and make the conversion in your snippet code (ie use ## for ?, !! for && and %% for =), or you can use a wrapper snippet, using the $modx->runSnippet(’snippet-name’, array(’parameter1’->’value1’, ’parameter2’->’value2’) function to actually run your 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
        • 9207 ☆ A M B ☆
        • 2,475 Posts
        Ah, but it ain’t logical at all... I’ve just written my own argument parser for a CRUD project I’m working on, so I know that one COULD write regular expressions to match any data between the back-ticks as the parameter value, e.g.

        $pattern='/`(.*)`/U'


        So really my question was what exactly is the behavior of the regex’s that grab Snippet parameters. Why doesn’t the parser iterate over the Snippet string like this:

                $snippet_pattern = '/^(.*)\s*\?/';
        
                $str='Snippet? &param1=`value one` &param2=`<a href="surprise">;) & :O</a>`';
        
                // First match is the Snippet name.  Then, trim off the Snippet name from the $str... then you have:
                $str='&param1=`value one` &param2=`<a href="surprise">;)</a>`';
        
                $param_pattern = '/^\s*\&([a-zA-z0-9)\s*\=\s*\`(.*)\`/U';
                // First match is the parameter name, Second match is the value
               // repeat until you got all the parameters/values...
        


        If it was done that way the only "off-limit" character would be the back-tick. There’s already been a fair amount of grief for people wanting to use html-entities as Snippet arguments, e.g. WebLoginPE using "&amp;" to separate drop-down values. And lots of folks fall into the trap that Snippets fail to execute when the calls use more than one line (I know that behavior isn’t consistent across browsers, but a regex tweak could probably fix it).

        My own frustration with this is when I want to pass in super-short strings to be used as chunks. It takes a speed hit to go look up in the db a one-line chunk when I could just specify it in the Snippet parameters. There are work-arounds... but... meh... am I missing something?
          • 3749
          • 24,544 Posts
          I haven’t tested it, but I suspect that in Revo you can put strings like the one in your example into the property set grid and they’ll be passed intact to the snippet.

          Workarounds for 0.9.6 include having your snippet process @FILE or @CHUNK bindings.

          You’re right that there’s a speed penalty, but if the parameter parsing were more complex, *all* snippets would take a speed hit.
            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
            • 9207 ☆ A M B ☆
            • 2,475 Posts
            Well, I’m not a guru on benchmarking, but I’m looking at the code now in /manager/includes/document.parser.class.inc.php around lines 800 or so (search for "function evalSnippets").

            There is copious use of the strpos() function in there. Is this faster than using preg_match() to match the stuff required? And yikes... so much use of double-quotes... don’t double quotes trigger the PHP parser? E.g. "$x" would evaluate while ’$x’ prints literally? How much of a speed bump is because of unnecessary use of double-quotes? Small example:

                                if (strpos($tempSnippetParams, "&") > 0)


            Should be:

                                if (strpos($tempSnippetParams, '&') > 0)


              • 3749
              • 24,544 Posts
              I think you’re looking at some of the reasons Revolution was created.  wink

              BTW, strpos is generally thought to be faster than preg_match but it actually depends on the particular task. I suspect that the parser has been extensively benchmarked and that the double quotes are necessary--perhaps to support legacy code.
                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
                • 9207 ☆ A M B ☆
                • 2,475 Posts
                I suspect that the parser has been extensively benchmarked and that the double quotes are necessary--perhaps to support legacy code.

                Unless I’m misreading something, I don’t think so... a lot of what I see in there is unnecessary, e.g. double-quoting string literals. I’m wondering if I a/b tested my homepage as-is vs. a version where I removed all unnecessary double-quotes, what would the performance boost be (if it’s even measurable). If it’s a 1% speed boost, it’d be worth it. Do you think apache’s ab tool would work for that?

                It does seem that the nature of the matching has a big effect on which is faster: preg_match vs. strpos. Here’s an example where preg_match was faster:
                http://dreamfall.blogspot.com/2008/02/php-benchmarks-strpos-vs-pregmatchall.html

                Looks like you can get some notable speed improvements by taking into consideration things like double-quotes:
                http://www.joomlaperformance.com/articles/performance/52_php_programming_tips_43_14_2.html
                  • 3749
                  • 24,544 Posts
                  LOL. I’ve spent some time second-guessing OpenGeek’s code. My batting average is close to zero. wink

                  The speed differences between single and double quotes are neglible and variable, especially in PHP5. For example, the first of these is actually faster than the second according to some benchmarking I’ve seen:

                  <?PHP 
                  
                  for ($i = 0; $i < 100000; $i++) {
                          $n = "string".$i;
                  } 
                  
                  ?>
                  
                  v2.php:
                  
                  <?PHP 
                  
                  for ($i = 0; $i < 100000; $i++) {
                          $n = 'string'.$i;
                  } 
                  
                  ?>


                  So it’s possible that switching to single quotes would actually slow things down.
                    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
                    • 9207 ☆ A M B ☆
                    • 2,475 Posts
                    Mmm... looks like we’re dealing with conflicting information... according to the bottom-most link I sent:
                    ’String’.$var is 28% faster than "String$var"

                    I guess the only way to really tell is to get a good benchmark tool going and try it.
                      • 25663 MODX Staff
                      • 12,272 Posts
                      Great discusssion Everett and Bob. Any ideas on improving our classic parser would be much appreciated and definitely JIRA worthy for review.
                        Ryan Thrash, MODX Co-Founder
                        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me