Using getChunk() To Separate Form and Content

Make your code more robust, and easier to maintain by using the MODX getChunk() method.

By Bob Ray
October 11, 2022
Using getChunk() To Separate Form and Content

After writing plenty of bad code, I’ve gradually learned that it pays to think about maintaining code when you write it. A common mantra in the world of web programming is that one should always separate form from content. Or in other words, model from view, or logic from presentation, or data from display, or code from content. The time spent doing this is paid back many times over later on when you need to make changes in your code.

In practice, this most often means trying to keep HTML and CSS out of your PHP code, and vice versa. One of the great benefits of MODX code is that it encourages you to do this in two ways. First, it doesn’t allow PHP code in Chunks. Second, it provides placeholders and the modx->getChunk() method to help you separate the logic of your code from the display that end users will see (also called the “presentation layer”).

The worst case of mixed PHP and HTML code I ever encountered was when I helped a friend modify a WordPress site based on the default, and very popular, Kubrick theme. My friend just wanted to modify the look of the heading at the top of the home page.

I discovered that the Kubrick theme was a surprising mishmash of HTML code, PHP code, calls to utility functions, and inline CSS code. It took me three full days to make a relatively minor change to the look of the header section of the home page. To be fair, I’m sure that a WordPress expert could have done it very quickly, and I’m told that the Kubrick theme has improved quite a bit since then.

getChunk()

In my early days with MODX, I used $modx->getChunk() in Snippets just to pull in content that I wanted to use in multiple places on the site, like header and footer Chunks. Here’s an example:

/* GetFooter snippet */
return $modx->getChunk('FooterChunk');

It wasn’t until later that I understood the value of the second argument to getChunk(), which can contain an array of placeholder names and their values. MODX will replace each placeholder in the Chunk with its corresponding value.

The code in the next two sections shows the wrong way to do it, and the right way using $modx->getChunk() with both arguments.

A Bad Mixture

Here is a classic example of mixing layers in a way that will make the code difficult to maintain:

$output = "";
$output .= '### User: ' . $username .  '' .
    'Email: ' . $email . '' . 'Phone: ' .
    $phone . '';

It’s embarrassing to look at Extras I wrote long ago and see lines like the ones above. How much cleaner and more sensible is it to put the display aspects in a Chunk and let the code handle just the data? The approach below produces the same output as the code above.

The Chunk:

### User: [[+username]]
Email: [[+email]]
Phone: [[+phone]]

The Code

$output = '';

$fields = (
   'username' => $username,
   'email' => $email,
   'phone' => $phone,
);

$output .= $modx->getChunk('myChunk', $fields);

The MODX getChunk() method is very fast, and if you decide to change the way users are displayed, it will be very easy to modify the Chunk or the CSS to improve the display without touching the code at all. Keep in mind, too, that every time you modify the PHP code, you risk temporarily breaking the site. Modifying the Chunk or the CSS could give you a less-than-perfect display, but it’s very unlikely to crash anything.

That said, there are times you need to construct the output dynamically like the first example above. If, for example, your code needs to modify the content or style of each line based on the values of the variables, you can make a case for putting that logic, and some HTML, in the code. Even then, though, you can often set a placeholder for the class of an HTML tag and use CSS to modify its appearance by making it bold, italic, hidden, or in a different font.

Suppose you’re creating a list of users by username, and you want to have the names of administrator users in bold. You could do something like this in your code:

In your RowTpl Chunk, used for each row of the list:

<li class="[[+user_class]]">
  [[+listed_user]]

In your Snippet, when you loop through the users:

$output = '';

/* Get array of users here */

foreach ($users as $user) {
    $fields = array();
    $fields['listed_user'] = $user->get('username');

    if ($user->isMember('Administrator')) {
       $fields['user_class'] = 'admin_user';
    } else {
       $fields['user_class'] = 'normal_user';
    }

    $output .= $modx->getChunk('UserTpl', $fields);
}

Now, the * tag will have a different class depending on the type of user. You can use CSS to control the display of administrator and non-administrator users without touching your code. This is a much better approach than putting <b></b> tags in your Snippet.

Too Much of a Good Thing

We can agree that in the first two examples of this article, the second version is vastly better than the first. That doesn’t mean, however, that it’s a good idea to put everything in a Chunk that can go in one. Before moving content down to another level with nested MODX tags, or a complex conditional output modifier, think about whether you really have a reason to do so.

We have looked at the disadvantages of excessive nesting of MODX tags in my previous article.


Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.