Creating and Using Utility Snippets

Learn about utility snippets — how to create and use them.

By Bob Ray  |  May 13, 2025  |  8 min read
Creating and Using Utility Snippets

If you read the MODX Forums, you may occasionally see posts with a suggestion like "Just use a utility snippet," followed by some code. If you're not familiar with the concept you may not know what a "Utility Snippet" is, or how to use one. If you already know, you can skip this article.

What is a Utility Snippet?

If you're not familiar with the term, you might think that a utility snippet is some special kind of snippet. It's not. It's just a regular snippet that's used in a different way. Most snippets in MODX are intended to run automatically when certain pages are visited. Wayfinder and getResources are obvious examples.

What's different about a utility snippet is that it's not intended to be run when someone visits a front-end page. Rather, intended to be run from the Manager, by a Manager user at a specific time, for a specific purpose.

Some Examples

You might want to use a utility snippet to add a batch of users to a specific user group. Another use would be to correct a spelling error or change some string (e.g., the name of an organization) that appears on many pages (though in these cases, the CustomSearch extra will do the job with a lot less effort). I faced this long ago at Bob's Guides when the spelling of the platform changed from "modX" to "MODX."

In earlier versions of MODX, upgrading MODX could make some of your pages disappear because their uri field was empty. You could solve this by loading and saving every page, but using a utility snippet that loads and saves all pages would be a lot easier, especially if your site has a lot of pages. Now MODX has the "Refresh URIs" option (under Manage -> Clear Cache) on the top menu. If you still have an older version of MODX, the utility snippet might still come in handy when you upgrade. We'll use this case for an example, because it's so simple.

Creating the Snippet

This is just like creating any snippet. Right-click on the Snippets folder in on the Elements tree in the Manager and select "New Snippet". Call the snippet RefreshAllUris and paste in this code:

$docs = $modx->getCollection('modResource');
$count = 0;
foreach ($docs as $doc) {
    $doc->save();
    $count++;
}

return '### Refreshed ' . $count . ' Resources';

The code simply gets all the resources, then loops through them, saving each one. We added a counter and a success message, so we can tell that the snippet has actually run successfully. It's a good practice to always have a utility snippet return some kind of success message. Otherwise, there's no easy way to tell if it has actually run. Here's a version for MODX 3:

$docs = $modx->getCollection('MODX\Revolution\modResource');
$count = 0;
foreach ($docs as $doc) {
    $doc->save();
    $count++;
}

return '### Refreshed ' . $count . ' Resources';

The only difference is in the first line where modSnippet is changed to MODX\Revolution\modSnippet. The prefix (MODX\Revolution\) is used because MODX 3 uses that prefix on most of the MODX objects (modSnippet, modPlugin, modChunk, modTemplate, etc.). Technically speaking, the prefix is called a "namespace." Namespaces are used throughout MODX 3, and I've written about them in previous articles.

At this writing, the prefix/namespace is not really necessary to get the code to run in MODX 3, but leaving it out will cause an error message to appear in the MODX Error Log, unless the log_deprecated System Setting is turned off.

The snippet above is a good base for future utility snippets since it gets all resources on the site and saves them all. With small modifications, you can add code to make changes to any of the resource fields before saving each resource.

Running the Snippet

In the very old days of MODX, there was actually a button on the Create/Edit Snippet panel that let you execute the snippet. I can see why it was removed, but it would be nice if it still existed and only appeared for members of the Administrator group. Instead, we just have to create a resource, put a tag for the snippet in the resource content of a page, and visit the page.

Create a page called RefreshUris. Make sure it's unpublished so others can't run the snippet. In the Resource Content field, put this tag:

[[!RefreshAllUris]]

Save the resource. Now, just right-click on the resource in the tree and select "View" (or whatever it's called in your version of MODX). That's all there is to it. As an Administrator, you should have the view_unpublished permission. That will let you view the page from the Manager and have the snippet run without publishing the page.

Actually, it doesn't matter what the resource is called, so you might want to call it something like "Utility Snippet". That way you can use it to run any utility snippets just by changing the snippet tag in the Resource Content field to the name of the snippet you want to run.

Another Slightly more Complex Example

Earlier in this article, I mentioned the idea of using a utility snippet to add users to a user group. Let's see what that would look like:

/* You can add as many users her as you like, just make sure
   there are no spaces and all are separated by commas. */

$usernames = 'BobRay,JaneDoe,JoeBlow';
$output = '';
$userGroupName = 'MyUserGroup';
$roleName = 'SomeRole';

/* Make sure User Group exists, exit with warning if not */
$group = $modx->getObject('modUserGroup', array('name' => $userGroupName));
if (empty($group)) {
    $output .= '<br>' . 'Usergroup ' . $userGroupName . ' not found';
}

$role = $modx->getObject('modUserGroupRole', array('name' => $roleName));

/* Make sure Role exists, exit with warning if not */
$role = $modx->getObject('modUserGroupRole', array('name' => $roleName));
if (empty($role)) {
    $output .= '<br>' . 'Role ' . $roleName . ' not found';
}

/* Only run this code if UserGroup and Role exist */
if ($role && $group) {

    $usernames = explode(',', $usernames);

    foreach ($usernames as $username) {
        $user = $modx->getObject('modUser', array('username' => $username));

        /* Make sure the user exists and warn if not */
        if (empty($user)) {
            $output .= '<br>' . 'User ' . $username . ' not found';
        } else {
            /* Make sure user is not already a member */
            if ($user->isMember($userGroupName)) {
                $output .= '<br>' . 'User ' . $username .
                    ' is already a member of ' . $userGroupName;
            } else {
                $user->joinGroup($userGroupName, $role);
                $output .= '<br>' . 'User ' . $username . ' added to ' . $userGroupName;
            }
        }
    }
}

return $output;

In the code above, we make sure the User, the Role, and the User Group both exist, because the code will crash if they don't. If they do, we check to see if the User exists, and then check to see if the User is already a member of the User Group. If not, we add the User to the User Group.

Notice that if the Role or the Group do not exist, the code inside the if ($role && $group) section will be skipped. We've already added the appropriate error messages to the $output variable, so those error messages (if any) will appear when we run the snippet, and none of the operations inside that section will execute.

The output displayed on the screen when the snippet is finished, will tell us exactly what the snippet did, or did not, do.

The check to see if the user is already a member is not strictly necessary, but it makes for cleaner output if the user is already a member, and it allows us to add users to the end of the list at any time and re-run the snippet.

The $output Variable

Near the top of the utility snippet above, we initialize the $output variable to an empty string. In the code below that, we add the messages to that end of that variable with the concatenation operator (.=). Each time it appears, the message is appended to what the string in $output variable already holds.

It's a good practice in PHP to have only one return statement, and to put it at the end of the code. This generally makes it easier to understand and maintain the code. This principle is sometimes violated. For example, if the Group or Role don't exist, we could have simply returned an error message as soon as we check for their existence. It's still a good general practice to avoid this, though, and should only be ignored to avoid running code that consumes significant time and/or resources, that could be avoided by an early return statement. That's not the case with our code, since none of the following code will be executed if the Group or the Role don't exist.

Take care when using the concatenation operator (.=), because if you forget and use the = operator without the dot, it will wipe out anything added earlier. This can lead to some confusing output that is missing key information.

PHP

Utility snippets are written in PHP, so you have to have some familiarity with that language to create one. The reason PHP is so popular for use with websites is that it's easy to learn (MODX itself and many of its extras are written in PHP). There are many resources on the web for learning it, and there's a whole appendix at the end of the first edition of MODX: The Official Guide that's basically a crash course in PHP.

You can use MODX without knowing any PHP at all, but knowing a little PHP will help you create and modify snippets to perform a wide variety of tasks that would take a great deal of time to do by hand in the MODX Manager. Knowing PHP can also help you understand the code of MODX extras, which will often help you figure out why they're not doing what you expect them to do.


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.