Topic: Problem with Special Character in Snippet Parameter  (Read 6057 times)

Pages: [1]   Go Down

#1: 3-Apr-2006, 04:51 PM

ddecjc
Posts: 61

I have already posted this in the Snippets forum because I thought it was a problem with the NewsListing snippet, but I've been advised that's it's a parser issue, so I'm reposting here:

I'm trying to set up a site in Spanish, and I need to be able to put an accented character in the &truncText parameter of the NewsListing. This is what I've got right now...
Code:
[!NewsListing? &tpl=`NewsListingTemplate` &startID=`2` &truncText=`Lea más...` &summarize=`99`!]
Problem is that everything after the word "Lea" is ignored, so it is only rendered as "Lea " (including the space).

Is there anything that I can do to fix this? Do I need to file a bug report? If I need to come up with a fix myself, can someone at least point me to the right file?

Thanks.
Dave

#2: 4-Apr-2006, 01:50 AM

Moderator

OpenGeek
MODx Co-Founder
Posts: 6,977

damn accurate caricatures...

WWW
Is there anything that I can do to fix this? Do I need to file a bug report? If I need to come up with a fix myself, can someone at least point me to the right file?

Yes, please file a bug report for this and I will take a look and try and slip it in the pending release.  If you're interested in looking and contributing potential solutions, feel free to take a look at /manager/includes/document.parser.class.inc.php, and start with the parseProperties() function.
Jason Coward
MODx Co-Founder
xPDO Founder
CTO @ Collabpad
work productively.
work intelligently.
work together.
Light is just a vibration of a note too. Everything is. You've got to keep that in mind.
  Frank Zappa

#3: 4-Apr-2006, 04:41 AM

ddecjc
Posts: 61

Bug report filed as FS#334. I listed severity as medium because it probably doesn't happen often enough to be high or critical for the general population. For me, however, it is critical. Thanks for looking at it. I will also try to take a look at the code you mentioned.
Dave

#4: 4-Apr-2006, 07:01 AM

ddecjc
Posts: 61

I looked in document.parser.class.inc.php and found the source of the problem. It is on line 763 in the evalSnippets function.
Code:
$tempSnippetParams = split($splitter, $tempSnippetParams);
When this line is executed to split the parameters into an array, the splitter is the "&" character. Since the html representation of many special character contains an "&" (for example, the html source for á is á), an unintended split occurs which results in the parameter string for
Code:
[!NewsListing? &tpl=`NewsListingTemplate` &startID=`2` &truncText=`Lea más...`!]
being split into
Code:
$tempSnippetParams = array(6) {
  [0]=>
  string(1) " "
  [1]=>
  string(26) "tpl=`NewsListingTemplate` "
  [2]=>
  string(12) "startID=`2` "
  [3]=>
  string(16) "truncText=`Lea m"
  [4]=>
  string(13) "aacute;s...` "
  [5]=>
  string(13) "summarize=`1`"
}
Dave

#5: 4-Apr-2006, 10:18 AM

Moderator

OpenGeek
MODx Co-Founder
Posts: 6,977

damn accurate caricatures...

WWW
I looked in document.parser.class.inc.php and found the source of the problem. It is on line 763 in the evalSnippets function.
Code:
$tempSnippetParams = split($splitter, $tempSnippetParams);

Try adding this line right before the line above with the split() call:

Code:
$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']);

This seems to work for me, but I haven't tested it exstensively yet.  If that doesn't work, try simply turning off the rich-text editor for a moment and pasting the code directly into the content source.  This will prevent the RTE from converting the special characters to HTML entities when being saved to the DB.
« Last Edit: 4-Apr-2006, 10:21 AM by OpenGeek »
Jason Coward
MODx Co-Founder
xPDO Founder
CTO @ Collabpad
work productively.
work intelligently.
work together.
Light is just a vibration of a note too. Everything is. You've got to keep that in mind.
  Frank Zappa

#6: 4-Apr-2006, 10:50 AM

ddecjc
Posts: 61

Try adding this line right before the line above with the split() call:
Code:
$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']);
That did the trick. Thanks!

If that doesn't work, try simply turning off the rich-text editor for a moment and pasting the code directly into the content source.  This will prevent the RTE from converting the special characters to HTML entities when being saved to the DB.
Doh! I didn't even think about it being stored that way because of the RTE. I was thinking that it got converted to html entity during parsing.

Thanks again!
Dave

#7: 11-Dec-2007, 07:22 AM


MrDutchy
Posts: 206

Why can't i call a snippet and initialize a parameter with a special character?
like [[MySnippet? &myVar=`abc¡de`]]
If i do in the snippet the variable content is truncated and if i return it, it is merely abc

We're running 0.9.6 on PHP Version 5.2.3 so the fix discussed in this thread should be allready applied correct?
However it looks like I still have trouble with this: http://modxcms.com/bugs/task/334

#8: 11-Dec-2007, 10:14 AM

Moderator

OpenGeek
MODx Co-Founder
Posts: 6,977

damn accurate caricatures...

WWW
This has always been a known limitation of snippet parameter values; you cannot use ? & or =.

The problem has been addressed for 0.9.7 release.
Jason Coward
MODx Co-Founder
xPDO Founder
CTO @ Collabpad
work productively.
work intelligently.
work together.
Light is just a vibration of a note too. Everything is. You've got to keep that in mind.
  Frank Zappa

#9: 14-Dec-2007, 01:34 PM


MrDutchy
Posts: 206

This has always been a known limitation of snippet parameter values; you cannot use ? & or =.

The problem has been addressed for 0.9.7 release.
I was experiencing the bug with ñ, ¿, ¡, á and the list goes on, not just the operators you listed.

Edit: just after posting it crossed my mind that every html encoded character obviously contains a &  Roll Eyes My bad Smiley

I ended up doing what you described earlier in this thread (switching the MODx document to non-rte, save, replace the html encoded chars with non encoded versions, save, switch back to rte). Thank god it were only 3 pages this time around Smiley
« Last Edit: 14-Dec-2007, 01:40 PM by MrDutchy »

#10: 14-Dec-2007, 01:44 PM

Coding Team

sottwell
Posts: 10,540

WWW
That's the RTE being overly helpful; you can stop that in the plugin configuration; change one of the settings to 'raw' (I forget exactly which setting that is).

Not being able to use & and = in snippet parameters is another matter; it has to do with how snippet parameters are parsed. You can work around that by making a "wrapper" snippet that only has
Code:
$modx->runSnippet('snippetName', array('param1'=>'value1', 'param2'=>'value2'));
return '';
sottwell.com has moved to a lovely Solaris 10 server!
Log in username guest, password guestuser.
Templates are now becoming available at http://sottwell.com/templates.html

#11: 17-Dec-2007, 01:59 PM


Phize
Posts: 84

WWW
Hello, all.
We cannot use special characters in snippet call, but i want to use them, too.
So, I tried to solve whole problem by parsing with Regex.
It seems to behave well, though some tests are not enough for relation to other functions.

Example of snippet call:
Code:
[[Snippet? param1  =  `?= ‵ [] &‵ &` &param2= &param3=[]?= &param4 &param?5=`[[Lea más...]]`]]
The result of parsing (var_dump $parameter):
Code:
array
  'param1' => string '?= ` [] &` &' (length=11)
  'param2' => string '' (length=0)
  'param3' => string '[]?=' (length=4)
  'param5' => string '[[Lea más...]]' (length=15)

The behavior of this hacked code
  • First parameter's '&' is completed automatically (ex. param1)
  • Parameters doesn't have value are ignored (ex. param4)
  • Every '?' in parameter's name are cut (ex. param5)
  • When a value is quoted with '`',  we can use special characters excluding '`' (ex. param1, 6)
  • When a value is not quoted with '`', we can use special characters excluding '`', '&', ']]' and space (ex. param2, 3)
  • Only when a value is quoted with '`', '‵' or '&#x2035' in the value is replaced with '`' (ex. param1)
  • Multi-byte characters also are parsed well on my local server (XAMPP+PHP 4.4.7 & PHP 5.2.4), but my tests are not enough (ex. param5)

The difference between this code and original code
  • Space characters of left and right of parameters are trimmed. (ex. param1)
    (In the case of original code, I guess first parameter of Example is parsed as 'param1  ' with space characters.)
  • '&' is parsed after parsing '‵' and '&#x2035'.
    The code in snippet call like '&paramx=`value`' is parsed as a parameter '&paramx' and a value. (ex. param1)
    (In the case of original code, '&' are replaced with '&' at first. Then parameters are parsed.
     Therefore, I guess the code is parsed as a parameter '&paramx'  and a value.)

MODx 0.9.5-0.9.6.1
method 'evalSnippets' in /manager/includes/document.parser.class.inc.php
(Line numbers are the one of version 0.9.6.1)

line 784 (before):
Code:
    function evalSnippets($documentSource) {
        preg_match_all('~\[\[(.*?)\]\]~', $documentSource, $matches);
line 784 (after):
Code:
    function evalSnippets($documentSource) {
        preg_match_all('~\[\[((?:.*?(?:`(?:[^`]|[^]]\])*?`)?)*?)\]\]~', $documentSource, $matches);


line 836 (before):
Code:
                // current params
                $currentSnippetParams= $snippetParams[$i];
                if (!empty ($currentSnippetParams)) {
                    $tempSnippetParams= str_replace("?", "", $currentSnippetParams);
                    $splitter= "&";
                    if (strpos($tempSnippetParams, "&") > 0)
                        $tempSnippetParams= str_replace("&", "&", $tempSnippetParams);
                    //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                    $tempSnippetParams= split($splitter, $tempSnippetParams);
                    $snippetParamCount= count($tempSnippetParams);
                    for ($x= 0; $x < $snippetParamCount; $x++) {
                        if (strpos($tempSnippetParams[$x], '=', 0)) {
                            if ($parameterTemp= explode("=", $tempSnippetParams[$x])) {
                                $fp= strpos($parameterTemp[1], '`');
                                $lp= strrpos($parameterTemp[1], '`');
                                if (!($fp === false && $lp === false))
                                    $parameterTemp[1]= substr($parameterTemp[1], $fp +1, $lp -1);
                                $parameter[$parameterTemp[0]]= $parameterTemp[1];
                            }
                        }
                    }
                }

line 836 (after):
Code:
                // current params
                $currentSnippetParams= $snippetParams[$i];
                if (!empty ($currentSnippetParams)) {
                    $tempSnippetParams= preg_replace("~^\s*\?\s*~", "", $currentSnippetParams);
                    $splitter= "&";
                    if (strpos($tempSnippetParams, $splitter) != 0)
                        $tempSnippetParams= $splitter . $tempSnippetParams;
                    //$tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
                    $snippetParamCount= preg_match_all("~" . $splitter
                                      . "([^" . $splitter . "=]*(?:=\s*`[^`]*`"
                                      . "|=[^" . $splitter . "\s]*"
                                      . "|[^" . $splitter . "]*))~", $tempSnippetParams, $matches);
                    $tempSnippetParams= @ $matches[1];
                    for ($x= 0; $x < $snippetParamCount; $x++) {
                        if (preg_match('~([^=\s]*)\s*=\s*`?([^`]*)`?~', $tempSnippetParams[$x], $parameterTemp)) {
                            $parameterTemp[2]= preg_replace("~&#0*8245;|&#x0*2035;~", "`", $parameterTemp[2]);
                            if (strpos($parameterTemp[2], "&amp;") > 0)
                                $parameterTemp[2]= str_replace("&amp;", "&", $parameterTemp[2]);
                            $parameterTemp[1]= str_replace("?", "", $parameterTemp[1]);
                            $parameter[$parameterTemp[1]]= $parameterTemp[2];
                        }
                    }
                }
« Last Edit: 17-Dec-2007, 02:18 PM by Phize »

#12: 17-Dec-2007, 05:08 PM

Coding Team

BobRay
Posts: 5,366

WWW
This has always been a known limitation of snippet parameter values; you cannot use ? & or =.

The problem has been addressed for 0.9.7 release.

A workaround is to replace those characters with AMP EQ and Q (or AMPERSAND, EQUALS, and QUESTIONMARK if you want to make sure to avoid collisions) in the snippet call and then convert them back at the top of your snippet. Just be sure to replace EQ before replacing Q if you use the short versions.  Wink

Bob
MODx info for newbies: http://bobsguides.com/MODx.html

#13: 8-May-2009, 10:40 PM


Andrey Nagikh
Posts: 499

Sorry for my ugly English

WWW
Sorry for upping thread. But I need to place special chars in snippet params.
I noticed the solution above was in modx code, but sine some time the line was commented (I use modx 0.9.6.3):
//    $tempSnippetParams = html_entity_decode($tempSnippetParams, ENT_NOQUOTES, $this->config['etomite_charset']); //FS#334 and FS#456
I uncomment it, got my functionality, and didn't get any errors (yet).

What does it means //FS#334 and FS#456?
And what problems should I expect after uncommenting this line?

Thank you! A.
Pages: [1]   Go Up
0 Members and 1 Guest are viewing this topic.