Weird problem with snippet calls

On a few sites I have a problem with snippet tags not working. The page won’t even load; my browser displays a “this page is not working” message. If I change this:

[[!snippetname? &someid=`3`]]

to this:

[[!snippetname?someid=`3`]]

then they work. Even within the same site, on some pages the normal way of making a snippet call works. On other pages, I have to use the URL-style method instead. What could be causing this?

Is this MODX 3?
Do you have pdoTools installed? (Just to ensure that the default MODX parser is the problem.)

No, it’s MODX 2.8.4, but this happens in previous versions as well. Yes, pdoTools is installed, just like it is on all my sites. pdoTools isn’t used in the snippet, though.

Where do you put that snippet?
Within a richtext editor?

Yes, in a rich text editor, but I checked the HTML and it is fine. In fact, if I add an “exit;” statement at the end of the snippet (preventing the full page from being constructed), the output of the snippet shows up just fine using the regular snippet call. So whatever goes wrong happens after the snippet output is created. The page never makes it into the site cache; the folder is there with the resource ID, but PHP cache files never get created for it.

One of the snippets with this problem is called “resources”. If I make a duplicate of that and call it “resourcesList”, then it works normally. I know there have been other instances of this on other sites, but I can’t remember which ones or what the snippet names are.

But as I said, the snippet call itself works fine. The problem is that the cache files don’t get created.
AND, on other pages, “resources” works just fine.

This snippet is uncached. It shouldn’t be executed before a cache file is created.
Where in the cache did you check?


Does it make any difference if you change the parser_class system setting back to “modParser”?


I can’t reproduce this, even with a snippet called “resources”. Is there maybe some other plugin that interferes?

SOME of the cache files get created. The cache files inside the cache folder with the page ID on it get created, but not the file in the resources->web->resources cache directory that would construct the full page. So, for page ID 595, using the regular snippet call setup, the cache directory looks like this:

Screen Shot 2022-09-14 at 10.05.38 AM

When I change the snippet call in the content to the URL-style, then it looks like this:

Screen Shot 2022-09-14 at 10.13.01 AM

Note the absence of the file “595.cache.php” in the first sample. The files inside the “595” folder get created whether or not I put “exit;” at the end of the snippet; the only difference is that the snippet output appears on the screen before it fails.

FYI, it doesn’t matter if the snippet is set to be cached or uncached; same result either way.

Can we get a look at the snippet and what it outputs?

I believe these cache files in the folder “595” are created by the snippet getResources or pdoResources.

Somewhere in the process an error must occur. Are there any error messages in the PHP error log?

Are there any plugins that run on an event like OnWebPagePrerender or maybe OnLoadWebDocument? Does it make a difference if you (temporarily) disable them?

The output is a simple list of pages or PDFs (depending on a TV setting in each resource). Tagger is used to categorize resources.

Sample tag:

[[!resources?cat=`94`]]

Here’s the snippet:

$atext = '';
if(!isset($tag)) { $tag = $cat; }
$tags = explode(',', $tag);
$numtags = count($tags);
$tagids = '';
$first = 1;
for ($i = 0; $i < $numtags; $i++) {
	if(!$first) { $tagids .= ' OR '; }
	$taglist = explode('|', $tags[$i]);
	$tagids .= '(EXISTS (SELECT * FROM mx_tagger_tag_resources WHERE resource=C.id AND ';
	for ($j=0; $j < count($taglist); $j++) {
		if($j) { $tagids .= ') AND (EXISTS (SELECT * FROM mx_tagger_tag_resources WHERE resource=C.id AND '; }
		$tagids .= 'tag='.$taglist[$j].')';
	}
	$tagids .= ')';
	$first = 0;
}
$sortorder = 'C.pagetitle';
$sortdirection = '';
if(isset($sort)) {
	if($sort == 'date') { $sortorder = 'C.publishedon DESC'; }
}
if(!empty($sortdir)) {
	if($sortdir == 'DESC') { $sortdirection = 'DESC'; }
	if($sortdir == 'ASC') { $sortdirection = 'ASC'; }
}


$q = "SELECT DISTINCT G.resource, C.pagetitle, C.publishedon FROM mx_site_content C
LEFT JOIN  mx_tagger_tag_resources G ON C.id=G.resource
WHERE $tagids AND C.published ORDER BY $sortorder $sortdirection";
$r = $modx->query($q);

$ress = array();
$i = 0;
$thisid = 0;
while ($row = $r->fetch(PDO::FETCH_ASSOC)) {
	$thisresource = $row['resource'];
	$res = $modx->getObject('modResource',$thisresource);
	if(isset($cat)) {
		$q2="SELECT DISTINCT resource FROM mx_tagger_tag_resources
		WHERE resource=".$thisresource." AND tag=".$cat;
		$r2 = $modx->query($q2);
		if ($r2->rowcount()>0) {
			if($res->published && !$res->deleted) {
				if(isset($linktoPDF)) {
					$atext .= '<p class="text-hang"><a href="' . $res->getTVValue('downloadfile') . '">'.$res->get('pagetitle').'</a></p>';
				} else {
					$atext .= '<p class="text-hang"><a href="/[[~' . $res->id . ']]">'.$res->get('pagetitle').'</a></p>';
				}
			}
			// }
		}
	} else {
		if($res->published && !$res->deleted) {
			if(isset($linktoPDF)) {
				$atext .= '<p class="text-hang"><a href="' . $res->getTVValue('downloadfile') . '">'.$res->get('pagetitle').'</a></p>';
			} else {
				$atext .= '<p class="text-hang"><a href="/[[~' . $thisresource . ']]">'.$res->get('pagetitle').'</a></p>';
			}
		}
	}
}


return $atext;

Sample output:

<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-emergency-mental-health-after-a-suicide-bombing">Terrorism and Disaster:  Emergency Mental Health After A Suicide Bombing</a></p>
<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-psychiatric-sequelae-of-a-911-survivor">Terrorism and Disaster:  Psychiatric Sequelae of a 9/11 Survivor</a></p>
<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-staphyloccocal-enterotoxin-b">Terrorism and Disaster:  Staphyloccocal Enterotoxin B</a></p>
<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-pneumonic-plague">Terrorism and Disaster: Pneumonic Plague</a></p>
<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-sarin">Terrorism and Disaster: Sarin</a></p>
<p class="text-hang"><a href="/resources/resource-master-list/terrorism-and-disaster-viral-hemorrhagic-fevers">Terrorism and Disaster: Viral Hemorrhagic Fevers</a></p>

I don’t use either of those snippets, and there are no errors in the logs.

Are you using the FastField extra? It replaces the MODX parser with its own.

No, not using FastField. Here’s what’s installed:

This problem is probably impossible to solve over the internet without a reproducible setup.

I reckon you have to debug it yourself. If you have no experience using a real debugger like Xdebug, then the next best thing is probably to use (temporary) log-statements in the code to figure out what is going on.

You say, that the snippet gets executed but no cache file gets created. Which means that the error must occur somewhere between these two events.

A first step could be to figure out, if the parser finishes successfully.
The parser is executed here:

If you add a log statement after $this->parseContent();,

$this->xpdo->log(modX::LOG_LEVEL_ERROR, "==> Output after parseContent():" . $this->_output);

does this get logged? Is the output correct?


A good way the analyse what the parser is actually doing, is to watch the mergeTagOutput function.

The $tagMap contains the tags and the content they are replaced with. You can log it with

$this->modx->log(modX::LOG_LEVEL_ERROR, "==> mergeTagOutput():" . json_encode($tagMap));

pdoTools has FastField included and uses its own parser, too

Yes, it gets logged. This is what was in the log:

[2022-09-22 20:09:11] (ERROR @ /home/jcstsonl/modxcore/model/modx/modresource.class.php : 499) ==> Output after parseContent():<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Terrorism and Disaster: What Clinicians Need to Know — Center for the Study of Traumatic Stress</title>
<base href="https://www.cstsonline.org/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="The Center for the Study of Traumatic Stress (CSTS) was established the psychological impact and health consequences resulting from the traumatic impact of:  1) the possibility, or actual use, of weapons of mass destruction (WMD) during combat, acts of terrorism or hostage events; 2) combat, peacemaking, peacekeeping, and operations other than war; 3) natural disasters such as hurricanes, tornadoes, or floods; and, 4) more common stress producing events such as physical assaults and motor vehicle, shipboard, or airplane accidents in both the uniformed and civilian communities.">
<meta property="og:type" content="website">
<meta property="og:title" content="Terrorism and Disaster: What Clinicians Need to Know">
<meta property="og:description" content="Medical Education series created through Uniformed Services University and RUSH Medical School collaboration (CME credits no longer available)
</style>
</body>
</html>


Which solved my problem! I noticed the failure after the og:description content. This grabs the content from the page to put in the description if there is no text entered in the MODX “introtext” field, and since there is only a short bit of text before the snippet tag, that tag becomes part of the header description, which messes it up. Adding custom text to introtext fixes the problem for this page.

For some reason, [[!resources?cat=94]] DOESN’T message up the description but still works on the page. And, this still doesn’t explain why changing the snippet name fixes the problem (why does a different snippet name NOT mess up the meta description content?). Anyway, I have a way out now and will update the script that creates the meta description content to work if there are snippets in the page content. I have code I’ve used on other sites to create the meta description. This site is much older, and I never put it in this one.

Did you use the limit (or ellipsis) output modifier in the “og:description” meta tag?

<meta property="og:description" content="[[*introtext:default=`[[*content:limit=`50`]]`]]">

Maybe the MODX tag [[!resources? &cat=`94`]] in the content just got cut in half by the limit modifier.

No, I don’t. I use PHP to process the content.