[MODX] Selecting Chunks – The Fast Way

It can make your life easier if you use the same Template on many pages, but you might not want them all to look exactly the same. Say, for example that you want to vary the header depending on which parent the page is under. You could do something like this:MODX logo

[code language=”html”]
[[*parent:is=`1`:then=`[[$headerChunk1]]`]]
[[*parent:is=`5`:then=`[[$headerChunk2]]`]]
[[*parent:is=`7`:then=`[[$headerChunk3]]`]]
[[*parent:is=`9`:or:is=`11`:then=`[[$headerChunk4]]`]]
[/code]

The performance of this code will be painfully slow because not only will each line have to be parsed and evaluated, the nested chunk tags will all execute and the all four chunks will be retrieved even though only one (or none) will be used.

You could improve the performance significantly by using Jason Coward’s Mosquitoes technique:

[code language=”html”]
[[[[*parent:is=`1`:then=`$headerChunk1`]]]]
[[[[*parent:is=`5`:then=`$headerChunk2`]]]]
[[[[*parent:is=`7`:then=`$headerChunk3`]]]]
[[[[*parent:is=`9`:or:is=`11`:then=`$headerChunk4`]]]]
[/code]

This will help a lot since at most only one chunk will be processed, but it will still be fairly slow. Each of the conditional tags will have to be parsed and then evaluated even though most of them won’t result in any output. What if we could use a single tag that didn’t contain a conditional statement?

 

The trick is to put the logic in a very simple snippet that uses the PHP switch statement to make the choice. You should be able to use this method even if you’re not that familiar with writing PHP code. If you care at all about page-load times (and you should), learning a little PHP is essential.

The Code

Here’s the tag:

[code language=”html”]
[[SelectChunk? &parentId=`[[*parent]]`]]
[/code]

 

Here’s the snippet code:

[code language=”php”]
<?php
/* SelectChunk snippet */

/* get the parent property from the $scriptProperties array */
$parent = $modx->getOption(‘parentId’, $scriptProperties, null);

/* Set a default chunk to use */
$chunkName = ‘MyDefaultChunk’;

/* Set $chunkName based on the parent */
switch($parent) {
case 1:
$chunkName = ‘headerChunk1’;
break;
case 5:
$chunkName = ‘headerChunk2’;
break;
case 7:
$chunkName = ‘headerChunk3’;
break;
case 9:
case 11:
$chunkName = ‘headerChunk4’;
break;
}

/* Return the appropriate chunk name*/
return $modx->getChunk($chunkName);
[/code]

 

The first line of PHP code in our snippet calls $modx->getOption() to get the &parentId property we sent in the snippet tag. The [[*parent]] tag inside the SelectChunk tag will be replaced with the content of the parent field of the resource, which as you probably know, holds the Resource ID of the resource’s parent (or 0 if the resource is at the root of the tree).

We discussed the $modx->getOption() method in the previous article. To review, it takes three arguments, separated by commas. In this case, the first one is the name of the property we’re looking for (parentId). The second argument is the array to look in, which in the case of snippet properties is always the $scriptProperties variable. The third (optional) argument is the default value to use if the property is not sent in the tag (in this case, null, because we want to make sure it’s not a number). As long as you include the &parentId property in the tag, the third argument will never be used.

To sum up that first line: after it executes the $parent variable will be set to the value sent in the &parent property. Since we’re using a tag to send the parent field. The variable will be set to the ID of the resource’s parent.

The switch Statement

The PHP switch statement is very simple. The first line tells PHP what value to use to select which options to execute (in parentheses). In this case, we’re “switching” on the value of the $parent variable. That’s followed by an opening curly brace ({), then the options, followed by a closing curly brace (}).

Each option starts with the word case followed by a value, then a colon. Indented below that is one or more lines of PHP code to execute followed by the break; statement, which tells PHP “break out of the switch statement”, in other words, to jump to the line after the closing curly brace.

When PHP encounters the switch statement, it checks the value in parentheses at the beginning, then looks for a case that matches it. If it finds one, it executes the code for that option, if not it does nothing and jumps past the end of the switch statement. It does this with blinding speed, using a jump table to jump to the appropriate case.

Notice the final two cases in our switch statement. There’s no break; statement between them. The code below them will execute if the parent is either 9 or 11. You can have as many cases as you like here and you could have similar sets of multiple cases anywhere in the switch statement if you want to execute the same code for multiple cases.

Remember, though, that a given section of PHP code needs a break; statement at the end. If it’s not there, the execution will “fall through” to the next case and its code will execute too. Leaving out the break; statement at the end of a case is the most common mistake made by people learning to use a switch statement. Multiple cases execute and they have trouble figuring out why.

We’re not using it here because we set our own default chunk name near the top of the snippet, but you can have a default case in a switch statement. Its code will execute of none of the other cases provides a match. That looks like this:

[code language=”php”]
default:
/* some code here */
break;
[/code]

By convention, it comes at the end of the switch statement, but it doesn’t have to. In fact, you can do this if you want to:

[code language=”php”]
default:
case 23:
case 34:
/* some code here */
break;
[/code]

The first two cases are unnecessary because the default case would execute anyway, but sometimes you want to make it clear what happens in those cases. The speed penalty is negligible.

In our example snippet, the code in each case of the switch statement simply sets the value of the $chunkName variable to the name of the appropriate chunk.

At the end of our code, we simply return the content of the selected chunk with return $modx->getChunk($chunkName). The contents of that chunk will replace the SelectChunk snippet tag.

Other Uses

With fairly minor modifications, the code above could be used to select chunks based on almost any characteristic of the current resource. The value at the top can be a string, so for example, you could send the pagetitle or the value of a TV in the snippet tag and adjust the code accordingly. You can also return a string directly rather than getting a chunk. Here’s an example:

[code language=”html”]
[[!SelectChunk? &tvValue=`[[*Tv1]]` ]]
[/code]

[code language=”php”]

$tvValue = $modx->getOption(‘tvValue’, $scriptProperties, ‘someValue’);
$output = ‘someValue’;
switch($tvValue) {
case ‘red’:
$output = "The color is red"
break;
case ‘blue’:
$output = "The color is blue"
break;
case ‘green’:
$output = "The color is green"
break;
}
return $output;
[/code]

Because we’re evaluating a string here, rather than a number, the value in each case has to be in quotes.

The only restriction for using a switch statement is that there has to be a single value in the parentheses at the top of the switch statement and the case has to match it. You can’t do any of these:

[code language=”php”]
case $parent > 5:
case $parent != 6:
case empty($parent):
[/code]

In those cases, you would have to construct an elseif tree like this:

[code language=”php”]
if ($parent > 5) {
/* some code */
} elseif ($parent != 6) {
/* some code */
} elseif (empty($parent)) {
/* some code */
} else {
/* default case here */
}
[/code]

Using the elseif method would still be *way* faster than creating the same options with conditional output modifiers.

 


For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , | Posted under MODX, MODX | RSS 2.0

Author Spotlight

Bob Ray

Bob Ray is the author of MODX: The Official Guide and over 30 MODX add-on components. He hosts Bob's Guides, a source of valuable information for MODX users, and has been very active in the MODX Forums with over 19,000 posts.

Leave a Reply

Your email address will not be published. Required fields are marked *