Upcoming Teaser with Multiple Resource Types

In the previous article, we looked at a way to display a “teaser” forMODX logo upcoming blog posts and set the &classKey property to select the resources you want. In this one, we’ll make a modification that allows a comma-separated list of class keys so you can display more than one kind of resource.

Tags and Chunks

As before, in order to maintain backward compatibility, neither the tag nor the Tpl chunks need to be modified, though you’ll modify the classKey property to show more than one resource type. The &parent property may also have to be modified. In the example below, we’ll show both blog articles and modDocument resources.

[code language=”html”]



New Code

In order to use the snippet with multiple resource types, we need use a comma-separated list of class keys in the &classKey property and modify the snippet to retrieve all of them:

[code language=”php”]
/* UpcomingTeaser snippet */

/* Save some typing and space */
$sp = $scriptProperties;

/* Get basic info from the properties */
$limit = $modx->getOption(‘limit’, $sp, ‘0’);
$parent = $modx->getOption(‘parent’, $sp, null);
$outerTpl = $modx->getOption(‘outerTpl’, $sp,
$innerTpl = $modx->getOption(‘innerTpl’, $sp,

$classKey= $modx->getOption(‘classKey’, $sp, ‘Article’, true);

/* Create an array of class keys from the &classKey property
and remove any leading or trailing spaces from the keys */
$classKeys = array_map(‘trim’, explode(‘,’, $classKey));

/* Create the query */
$query = $modx->newQuery(‘modResource’);

/* We only want articles that are unpublished children of
the blog container, and have a pub_date later than the
current time */
‘parent’ => $parent,
‘published’ => ‘0’,
‘pub_date:>=’ => time(),
‘class_key:IN’ => $classKeys,


/* This will make sure they are in chronological order */
$query->sortby(‘pub_date’, ‘ASC’);

/* Set the number of articles to be retrieved */

/* Get the articles */
$docs = $modx->getCollection(‘modResource’, $query);

if (empty($docs)) {
/* No upcoming resources, return nothing */
$output = ”;
} else {
/* No use getting this unless we have something to show */
$outer = $modx->getChunk($outerTpl);

/* Iterate through the docs formatting as we go */
foreach($docs as $doc) {
$fields = $doc->toArray();
$inner .= $modx->getChunk($innerTpl, $fields);
/* Plug the articles list into the outer Tpl chunk */
$output = str_replace(‘[[+upcoming_inner]]’, $inner, $outer);

return $output;



The only changes are the line that converts the property value to an array, the line where we create the query, the where clause of the query, and the line where we call getCollection() to get the resources.

We use explode() to convert the &classKey property to an array. If we could count on the user putting no spaces around the commas, we could do it with explode(',', $classKey), but people are used to putting a space after a comma and it’s a common mistake here. To correct it, we add array_map() and trim() to the code. The array_map() function is a handy method that calls another function on each member of the array it’s creating. The name of the function to be called is in quotes as the first argument to array_map. In this case it’s 'trim'. The trim() function removes leading and trailing spaces from a string, leaving any internal spaces alone. It also removes line feeds, tabs, and a few other things that we don’t really need to worry about here, but it’s very fast.

In the line that creates the query and the getCollection() call, we’ve changed the class to modResource, so any object that extends modResource will be eligible. This will include modDocument, Article, modSymLink, modWebLink, and modStaticResource, as well as any other objects that extend modResource. All of these can be used in the &classKey property.

Finally, in the where clause of the query, we’ve added the additional criterion: 'class_key:IN' => $classKeys,. This tells xPDO that we only want resources with the specified class keys.


There are situations where this isn’t going to work. It doesn’t include template variables, though you could add code to set placeholders for any TVs you need. It doesn’t allow us to select resources based on TV values, and modifying the code to do this would be fairly complex.

The snippet, as written, also doesn’t allow all the bells and whistles that come with getResources such as the ability to have first, last, or alternate Tpl chunks, and the option to include or exclude specific resources.

A more serious limitation is that our snippet doesn’t allow for multiple parents. We could allow a comma-separated list of parents in a &parents property, get its value in the snippet, use explode() on that property as we did with &classKey, and add another criterion to the where clause:'parent:IN' => $parents. The problem with this is that it would only get the immediate children of the listed parents. The getResources snippet will get all the descendants of the specified parents (that, and the ability to filter by TVs, help to explain why getResources can be so slow).

For more complex use cases, you’re forced to fall back on getResources or pdoResources. The only alternative would be to add the features of those snippets to ours, which is seldom worth the effort. You can call getResources or pdoResource in a snippet using $modx->runSnippet(). The only advantage to doing so would be the ability to return nothing if no results were returned. We’ll look at that option in the next article.


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 <a
href=”http://bit.ly/YgFGHl”>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 *