Why does the long version of this with the extra fake tag work but the short version does not? It seems like they should produce the same output. The idea is to not show entries with due dates before today. The short one always says “hide” no matter what.
long: [[+fake:default=`[[+nowdate:default=`now`:strtotime]]`:lt=`[[+due_date:strtotime]]`:then=`show`:else=`hide`]]
short: [[+due_date:strtotime:gt=`[[+nowdate:default=`now`:strtotime]]`:then=`show`:else=`hide`]]
So the problem here is, that the placeholder [[+nowdate]] doesn’t actually exists.
The MODX parser first tries to parse [[+nowdate:default=`now`:strtotime]]. Because the placeholder doesn’t exist, the tag is not processed and left as is. Then the parser processes the outer tag and compares the timestamp value for the date with the literal string [[+nowdate:default=`now`:strtotime]] (instead of the current timestamp).
To avoid the issue, always use uncached tags (for the outer and the nested tag):
[[!+due_date:strtotime:gt=`[[!+nowdate:default=`now`:strtotime]]`:then=`show`:else=`hide`]]
1 Like
I thought maybe it had something to do with parsing/caching. But calling the tags uncached doesn’t seem to help. In fact, if I call [[!+due_date]] uncached it produces no output at all for some reason. Removing the ! it works again.
So where exactly is this [[+due_date]] placeholder used on your site?
Is it in a chunk that gets used by getResources/pdoResources to output the information about a page? Is getResources/pdoResources called cached or uncached?
The thing is, that when everything is cached, the comparison with the “nowdate” will be at the point in time when the resource is cached, and not at the time when a user requests the page.
[[+due_date]] is being used in the template chunk for a cached call to [[migxLoopCollection]]. Calling [[!+nowdate]] uncached is no problem, and makes sense. Calling [[!+due_date]] uncached also makes sense but seems to not work for some reason.
Edit: calling [[!migxLoopCollection]] uncached seems to make the short version work. I’m still confused why the long version worked with the cached call when the short one didn’t though. It seems like they should both work, or not work, the same.
Alternatively, if you want to make it work with a cached snippet call ([[migxLoopCollection]]), you have to swap the positions of the placeholders:
[[!+nowdate:default=`now`:strtotime:lte=`[[+due_date:strtotime]]`:then=`show`:else=`hide`]]
[[+due_date:strtotime]] gets processed and replace when the snippet runs.
The expression in the cache file will be (something like)
[[!+nowdate:default=`now`:strtotime:lte=`1764581929`:then=`show`:else=`hide`]]
and then evaluated on every request.
The MODX parser does 2 runs. In theory, first all cached tags are parsed and the result is written to the cache file. Then the uncached tags are parsed (on every request).
But the parser has some “leniency” and cached tags can be treated as uncached (and their execution postponed), if they can’t be resolved.
If you use the code
[[+fake:default=`[[+nowdate:default=`now`:strtotime]]`:lt=`[[+due_date:strtotime]]`:then=`show`:else=`hide`]]
[[+fake]] can’t be evaluated during the processing of the cached tags, so it’s treated as an uncached tag. What gets written to the cache file is (something like)
[[+fake:default=`[[+nowdate:default=`now`:strtotime]]`:lt=`1764581929`:then=`show`:else=`hide`]]
(Notice that [[+due_date:strtotime]] got replaced with the actual value, as this placeholder was available.)
So in the end, the “long version” works quite similar to the other solution I posted above
([[!+nowdate:default=`now`:strtotime:lte=`[[+due_date:strtotime]]`...]]).
But I would prefer the second one, as it is more explicit about which tag should be executed cached and which one uncached.
1 Like
I see. I think I understand better now. Thank you!