I don't think that the problems has anything to do with any over-complicated code structure.
First, because it worked perfectly well before the upgrade to Revo 2.1.
Second, because the recursive parser is the power of MODX Revo, and if I can't get a snippet call work in a mere chunk, there is simply no point using such a recursive system.
That said, I must admit that over-complication was my first hypothesis too... but the original structure is way more complex that what I posted above, which is reduced to the minimum to get the problem reproduced.
To ensure that my problem was not related to my site structure at all, I built up a test case on a fresh Revo 2.1.5 install: one snippet, one chunk, one page and the default template. I really doubt this configuration can be seen as "complex", and yet the bug is still there.
Here are the details, if anyone wants to give it a try:
- the page:
<p>[[PlaceholderBugSnippet? &p1=`value1` &p2=`value2` ]]</p>
<p>[[PlaceholderBugSnippet? &p1=`` &p2=`` ]]</p>
<p>[[PlaceholderBugSnippet? &p1=`value1` ]]</p>
<p>[[PlaceholderBugSnippet? &p2=`value2` ]]</p>
<p>[[PlaceholderBugSnippet]]</p>
<hr/>
<p>[[$PlaceHolderBugChunk? &arg1=`value1` &arg2=`value2`]]</p>
<p>[[$PlaceHolderBugChunk? &arg1=`` &arg2=``]]</p>
<p>[[$PlaceHolderBugChunk? &arg1=`value1`]]</p>
<p>[[$PlaceHolderBugChunk? &arg2=`value2`]]</p>
<p>[[$PlaceHolderBugChunk]]</p>
- the chunk (it just calls the snippet):
<span class="chunk">[[PlaceholderBugSnippet? &p1=`[[+arg1]]` &p2=`[[+arg2:default=`novalue`]]` ]]</span>
- the snippet (it displays the arguments, first with no processing at all, then inserting spaces between the characters, in order to avoid later parsing):
<?php
$result= 'P1:';
$param= $scriptProperties['p1'];
for ($i= 0; $i < strlen($param); $i++) $result.= ' '.$param[$i];
$result.= ' // P2:';
$param= $scriptProperties['p2'];
for ($i= 0; $i < strlen($param); $i++) $result.= ' '.$param[$i];
return 'Output: P1: '.$scriptProperties['p1'].' // P2: '.$scriptProperties['p2'].'<br />Input : '.$result;
- the template is the default one, which simply renders the page content in a minimalistic HTML document.
Now here is what I get when I display the page:
Output: P1: value1 // P2: value2
Input : P1: v a l u e 1 // P2: v a l u e 2
Output: P1: // P2:
Input : P1: // P2:
Output: P1: value1 // P2:
Input : P1: v a l u e 1 // P2:
Output: P1: // P2: value2
Input : P1: // P2: v a l u e 2
Output: P1: // P2:
Input : P1: // P2:
------------------------------------------------------------------
Output: P1: value1 // P2: value2
Input : P1: v a l u e 1 // P2: v a l u e 2
Output: P1: // P2: novalue
Input : P1: // P2: n o v a l u e
Output: P1: value1 // P2: novalue
Input : P1: v a l u e 1 // P2: [ [ + a r g 2 : d e f a u l t = ` n o v a l u e ` ] ]
Output: P1: // P2: value2
Input : P1: [ [ + a r g 1 ] ] // P2: v a l u e 2
Output: P1: // P2: novalue
Input : P1: [ [ + a r g 1 ] ] // P2: [ [ + a r g 2 : d e f a u l t = ` n o v a l u e ` ] ]
What it shows us is:
- when calling the snippet directly (outside the chunk), there is absolutely no problem.
- When the placeholder is provided to the chunk, there is no problem, and when an empty value is explicitly given, it works too;
- when the placeholder is omitted, the snippet gets the "raw" unparsed value, would an output processor be used or not;
- when the snippet returns, the parser takes back control and does the placeholder replacements, which explains the difference between [tt]Input[/tt] and [tt]Output[/tt] lines (note that this makes the problem quite hard to spot, because you need a trick to reformat the output, just to see what happens).
What is abnormal is that the snippet receives unparsed data, which, in my opinion, should never occur. If a placeholder is not present, the snippet should receive en empty string (or a default value if the 'default' output processor is used)... this is how it used to work before 2.1.
I have always thought placeholders in chunks were simply like arguments (that's the way I use them), but perhaps they have a different meaning in MODX developers' mind. If I'm wrong, would someone explain me why and what I should do to get things properly work on Revo 2.1.
If there is no misunderstanding, there is probably a bug in the parsing chain, but I'm afraid I won't be able to spot and solve it without diving a lot more into MODX's architecture.
At the moment, I have found different workarounds to this issue:
1. explicitly setting the placeholder values in each chunk call (quite unsatisfactory because it forces to modify every chunk call, and there may be many);
2. creating default properties for the chunk, corresponding to the placeholers I use (in this case there is no more need for the output processors: the default values of the properties play this role).
3. calling the snippet uncached (by inserting an exclamation mark either before [tt]PlaceholderBugChunk[/tt] in the page, or before [tt]PlaceholderBugSnippet[/tt] in the chunk) but, not mentioning the fact that this couldn't be an option on a production environment, it strangely "solves" the problem only partially: it works for [tt]arg2[/tt] (the placeholder with the 'default' output processor), but has no effect on [tt]arg1[/tt], which is still retrieved unparsed.
The "default properties" trick seems to be reasonably good, and I'm gonna use it until a better solution is found.
However, I still don't understand why Revo 2.1 behaves this way, and still expect somebody's help to enlighten this mystery.
Thank you for reading... and thank you again for your help if you are to post an answer