正規表現を使って、スニペットでは通常使えない文字(「]]」、「`」を含む)を使えるようにできたっぽいので貼ってみます(強引っぽいですが)。
パラメータはバッククォートあり・なし、値なしのどの場合でも通常とほぼ同じような動作になります。
スニペットコールの例:[[Snippet? param1 = `?= ‵ [] &‵ &` ¶m2= ¶m3=[]?= ¶m4 ¶m?5=`[[Lea más...]]`]]
パラメータ名と値の解析結果($parameterのvar_dump):array
'param1' => string '?= ` [] &` &' (length=11)
'param2' => string '' (length=0)
'param3' => string '[]?=' (length=4)
'param5' => string '[[Lea más...]]' (length=15)
- 通常の動作と同様に、1つ目のパラメータ名の「&」は補完されます。(param1の例)
- 通常の動作と同様に値のないパラメータは無視されます。(param4の例)
- 通常の動作と同様にパラメータ名の「?」は「?」の部分だけが削除されます。(param5の例)
- 値をバッククォートで囲んだ場合は、「`」以外の文字が使えます。(param1, 6の例)
- 値をバッククォートで囲まない場合は、通常使える文字に加えて「`」、「&」、空白文字以外の記号が使えます(param2, 3の例)。
- 値をバッククォートで囲んでいる場合に限って、数値文字参照「‵」や「‵」が「`」に変換されます。(param1の例)
- マルチバイト文字は、うちのローカル環境(XAMPP+PHP 4.4.7&PHP 5.2.4)では問題ないみたいですが詳しくテストしてません。(param5の例)
パラメータ名と値をつなぐ「=」の前後の空白文字の扱いと「&」の扱いだけは、パース結果「param1」のように通常のMODxの動作とは異なります。
通常のMODxの動作は、1番目のパラメータ名は「param1 」になりますが、このコードでは前後の空白文字は削除したほうが自然だと思うのでそうしてます。
また、通常は「&paramx=`value`」という文字があると最初に「&」が「&」に変換され、その後「paramx=`value`」という一つのパラメータとして扱われますが、このコードではバッククォートの処理の後に変換しているためパラメータとしては扱われません。
あと「[[」と「]]」、「`」は相変わらず使えないです 
「[[」と「]]」はevalSnippetsメソッドの1行目の正規表現を工夫すればできそうな気もしないでもないですが…2007/12/15 全ての文字を使えるようにしてみました。1つ目のパラメータ名に「&」が省略されていた場合にパラメータが無視されていた(通常の動作と異なる)のと、その他の細かい処理を修正しました。MODx 0.9.5~0.9.6.1
/manager/includes/document.parser.class.inc.php evalSnippetsメソッド内
(行数は 0.9.6.1 のものです。)
784行目あたり~(変更前): function evalSnippets($documentSource) {
preg_match_all('~\[\[(.*?)\]\]~', $documentSource, $matches);
784行目あたり~(変更後): function evalSnippets($documentSource) {
preg_match_all('~\[\[((?:.*?(?:`(?:[^`]|[^]]\])*?`)?)*?)\]\]~', $documentSource, $matches);
836行目あたり~(変更前): // 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];
}
}
}
}
836行目あたり~(変更後): // 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("~�*8245;|�*2035;~", "`", $parameterTemp[2]);
if (strpos($parameterTemp[2], "&") > 0)
$parameterTemp[2]= str_replace("&", "&", $parameterTemp[2]);
$parameterTemp[1]= str_replace("?", "", $parameterTemp[1]);
$parameter[$parameterTemp[1]]= $parameterTemp[2];
}
}
}