
MODX Revolution - a pair of crutches for unusual situations
MODX is certainly a cool CMF, but sometimes you get to grips with such trifles that strain. I will not cry in this topic what all around are bad, but I'm so good. Take, for example, the Revolution branch and dissect it. And so that you do not lose interest in this article, here is a short outline of the article:
Create a set of parameters. We add X parameters to it, and then we understand that we parted. Trying to find the delete button ...

In general, nothing worked for me. I had to look for another way to remove the parameter.
Solution : we open an unnecessary parameter for editing and completely copy all the data of another desired parameter (supposedly trying to overwrite the old parameter with new data).
Corollary: We can overwrite the value of the desired parameter.
We simulate this situation: several contexts, each setting has its own settings.
If there are several sites in the admin panel, then, as a rule, a key such as site_name is redefined in the context settings. Now imagine your company has always positioned its name as Cool Peppers .

What do you think, what result will we see in the front-end? Right, just Cool.
Solution : use special characters instead of brackets.
And what about those who use 1 template in several contexts and want to specify a certain set of parameters for JS code as a key? There, special characters will not help and one chunk can not do.
There are already two solutions
MODX has long had a feature like
Now let's create a simple
install phpthumbof and create
Let's make a call to this all on the page like this:
But it’s bad, the first time the phpthumbof snippet is called, the string [[+ item]] comes in and only with all subsequent ones the parsed placeholder is resolved

Solution : Store such problematic chunks in files. Those. check the static box and select a file

Another solution from bezumkin : Replace parseChunk with getChunk.
We will carry out the experiment as follows: create a new document with the blank template. We leave the content and everything else empty. Check that the checkbox is worth caching.
before the line
Well, open our page in the browser. o0! number 1..2..3 The question is which mother is your ... Blank page. What is there to parse? We look carefully at the source
Thus, even on a blank page, we trigger the same event 3 times. I’m scared to think about what will happen to those sites that still have some code hanging on this event.
artdevue for the experiment checked how many times this function will be executed under various conditions. so we have the following plate.
On one of the working sites, I opened a folder with a cache and almost fell off a chair. 1 page in cache takes from 50 to 200 KB. No, this can of course be normal, but the cache is updated every time documents are changed. Updated 1 document - all cached pages are deleted. And if 100 pages? 1000? This is pulling a few MB. What if news is added every day?
PS Renamed the topic to look less whiny and defiant
- Backend parsing
- Deepening in settings
- Work with nested chunks
- We observe the work of the parser
- Powerful cache
Removing a parameter from a parameter set
Create a set of parameters. We add X parameters to it, and then we understand that we parted. Trying to find the delete button ...

In general, nothing worked for me. I had to look for another way to remove the parameter.
Solution : we open an unnecessary parameter for editing and completely copy all the data of another desired parameter (supposedly trying to overwrite the old parameter with new data).
Corollary: We can overwrite the value of the desired parameter.
Key values in context settings
We simulate this situation: several contexts, each setting has its own settings.
If there are several sites in the admin panel, then, as a rule, a key such as site_name is redefined in the context settings. Now imagine your company has always positioned its name as Cool Peppers .

What do you think, what result will we see in the front-end? Right, just Cool.
Solution : use special characters instead of brackets.
And what about those who use 1 template in several contexts and want to specify a certain set of parameters for JS code as a key? There, special characters will not help and one chunk can not do.
There are already two solutions
- The first solution : create your own snippet and, depending on the context, give the desired chunk using getChunk.
- Second solution : For each context, create your own chunk and write [[$ name _ [[* context_key]]]] in the template instead of the key. But be that as it may, this record looks out of tune ... Thanks artdevue for this solution .
Work with nested chunks
MODX has long had a feature like
getChunk
(parseChunk, for example, depends on it).
public function getChunk($chunkName, array $properties= array ()) {
$output= '';
if (array_key_exists($chunkName, $this->sourceCache['modChunk'])) {
$chunk = $this->newObject('modChunk');
$chunk->fromArray($this->sourceCache['modChunk'][$chunkName]['fields'], '', true, true);
$chunk->setPolicies($this->sourceCache['modChunk'][$chunkName]['policies']);
} else {
$chunk= $this->getObject('modChunk', array ('name' => $chunkName), true);
if (!empty($chunk) || $chunk === '0') {
$this->sourceCache['modChunk'][$chunkName]= array (
'fields' => $chunk->toArray(),
'policies' => $chunk->getPolicies()
);
}
}
if (!empty($chunk) || $chunk === '0') {
$chunk->setCacheable(false);
$output= $chunk->process($properties);
}
return $output;
}
Now let's create a simple
snippet
0){
foreach($phs as $item){
$data.=$modx->parseChunk($tpl,array('item'=>$item,'time'=>time()));
}
}
return $data;
install phpthumbof and create
chunk
[[+time]]: [[+item]] - [[!phpthumbof? &input=`[[+item]]` &options=`&h=150&f=jpg`]]
Let's make a call to this all on the page like this:
[[!test? &tpl=`test` &phs=`/assets/1.jpg,/assets/2.jpg`]]
But it’s bad, the first time the phpthumbof snippet is called, the string [[+ item]] comes in and only with all subsequent ones the parsed placeholder is resolved

Solution : Store such problematic chunks in files. Those. check the static box and select a file

Another solution from bezumkin : Replace parseChunk with getChunk.
We observe the work of the parser
We will carry out the experiment as follows: create a new document with the blank template. We leave the content and everything else empty. Check that the checkbox is worth caching.
Now open the processElementTags function from the file /core/mode/modx/modparser.class.php
public function processElementTags($parentTag, & $content, $processUncacheable= false, $removeUnprocessed= false, $prefix= "[[", $suffix= "]]", $tokens= array (), $depth= 0) {
$this->_processingTag = true;
$this->_processingUncacheable = (boolean) $processUncacheable;
$this->_removingUnprocessed = (boolean) $removeUnprocessed;
$depth = $depth > 0 ? $depth - 1 : 0;
$processed= 0;
$tags= array ();
/* invoke OnParseDocument event */
$this->modx->documentOutput = $content;
$this->modx->invokeEvent('OnParseDocument', array('content' => &$content));
$content = $this->modx->documentOutput;
unset($this->modx->documentOutput);
if ($collected= $this->collectElementTags($content, $tags, $prefix, $suffix, $tokens)) {
$tagMap= array ();
foreach ($tags as $tag) {
$token= substr($tag[1], 0, 1);
if (!$processUncacheable && $token === '!') {
if ($removeUnprocessed) {
$tagMap[$tag[0]]= '';
}
}
elseif (!empty ($tokens) && !in_array($token, $tokens)) {
$collected--;
continue;
}
if ($tag[0] === $parentTag) {
$tagMap[$tag[0]]= '';
$processed++;
continue;
}
$tagOutput= $this->processTag($tag, $processUncacheable);
if (($tagOutput === null || $tagOutput === false) && $removeUnprocessed) {
$tagMap[$tag[0]]= '';
$processed++;
}
elseif ($tagOutput !== null && $tagOutput !== false) {
$tagMap[$tag[0]]= $tagOutput;
if ($tag[0] !== $tagOutput) $processed++;
}
}
$this->mergeTagOutput($tagMap, $content);
if ($depth > 0) {
$processed+= $this->processElementTags($parentTag, $content, $processUncacheable, $removeUnprocessed, $prefix, $suffix, $tokens, $depth);
}
}
$this->_processingTag = false;
return $processed;
}
before the line
$this->_processingTag = true;
add static $test; echo ++$test."
";
Well, open our page in the browser. o0! number 1..2..3 The question is which mother is your ... Blank page. What is there to parse? We look carefully at the source
$this->modx->invokeEvent('OnParseDocument', array('content' => &$content));
Thus, even on a blank page, we trigger the same event 3 times. I’m scared to think about what will happen to those sites that still have some code hanging on this event.
artdevue for the experiment checked how many times this function will be executed under various conditions. so we have the following plate.
Condition | Iterations |
---|---|
[[snippet]] | 2 |
{{$ chunk}} | 2 |
Empty page | 3 |
[[num? input = `1000`]] | 5 |
[[* pagetitle: num]] | 6 |
[[num? input = `[[* pagetitle]]`]]] | 7 |
Nonexistent snippet | 23 |
Nonexistent chunk | 23 |
Powerful cache
On one of the working sites, I opened a folder with a cache and almost fell off a chair. 1 page in cache takes from 50 to 200 KB. No, this can of course be normal, but the cache is updated every time documents are changed. Updated 1 document - all cached pages are deleted. And if 100 pages? 1000? This is pulling a few MB. What if news is added every day?
PS Renamed the topic to look less whiny and defiant