Overview

I am currently building an online cellular company web site, which requires a large amount of information to be populated throughout the site from APIs and multiple database applications.

In looking for ways to optimize the site and get as much of it cached as possible I created and implemented the following solution. Your mileage may vary, but I have yet to find a Snippet this will not work with, unless the Snippet requires itself in the page such as getPage (for pagination) and others.

The Main Wrapper

$snippetToRun = $scriptProperties ['snippet'];
$chunkToRefresh = $scriptProperties ['chunkName'];
$success = false;

/*
 * If we have a Snippet to run and a chunk to refresh keep going
 */
if (isset($snippetToRun) && isset($chunkToRefresh)) {

	/**
	 * Remove the Snippet name and Chunk name from the parameters 
     * to keep from passing them into runSnippet
	 */
	unset($scriptProperties ['snippet'], $scriptProperties ['chunkName']);

	/**
	 * Retrieve Chunk Object to store the output in
	 */
	$chunkObj = $modx->getObject('modChunk', array (
			'name' => $chunkToRefresh
	));

	/**
	 * Create the chunk if it does not exist, so we can store output
	 */
	if (! $chunkObj instanceof modChunk) {
		$chunkObj = $modx->newObject('modChunk', array (
				'name' => $chunkToRefresh
		));
	}

	/**
	 * If we have a chunk object move forward or just drop out leaving old data in tact
	 */
	if (is_object($chunkObj) && $chunkObj instanceof modChunk) {

		/**
		 * Execute Snippet
		 */
		$contents = $modx->runSnippet($snippetToRun, $scriptProperties);

		/**
		 * If contents exist overwrite chunk contents with the new output
		 */

		if ($contents) {
			$chunkObj->setContent($contents);
			$success = $chunkObj->save(false);
		}
	}
}

return ($success) ? $contents : 'Failed...';

Implementation

Place the wrapper code in an ACL protected page or an (un)published / hidden from menus page to periodically refresh the chunk from

View the wrapper page to create / update the chunk

Verify the chunk was created/ updated in the Element tree of the MODX Manager.

Note: if you have categories in the Manager you can place the chunk under the category of your choice and thereby benefit from any ACL's attached to them.

Warning: this wrapper doesn't care about ACLs, so be careful how you use it if you have sensitive or user contact information on the site.

Now we simply place our chunk, in this example: [[featuredPhones]] in the page where we call the Snippet

Remove the old Snippet call and reload the page a couple of times. Even the first load should show a dramatic decrease in parsing and loading times.

getResources Example

<div class="row-fluid">
[[refreshChunkContents
?snippet=`getResources`
&chunkName=`featuredPhones`
&includeTVs=`1`
&limit=`6`
&tpl=`getStoreItemsForSiteFront`
&parents=`94`
&depth=`0`
&processTVs=`1` 
&showHidden=`1` 
&tvFilters =`featured==yes` 
&sortdir=`ASC`]]
</div>

getResources Explanation


The site I am building utilizes Twitter's Bootstrap in MODX Revolution, so I decided to have the output isolated inside of a row-fluid on the Operations page which creates the static content.

I first call refreshChunkContents which is listed above. You may have noticed the concept here closely matches the getPage wrapper found in the Repository. The primary difference being this code makes the output static and cacheable via a modChunk.

A list of the relevant concepts are presented below:

  • ?snippet The name of the Snippet which will provide the output
  • &chunkName The name of the Chunk which will be used to store the Snippet output. Take special note: this is not the tpl being used by getResources to create the output
  • The rest of the properties belong to getResources.
  • ?snippet&chunkName are stripped from the properties being passed through to getResource
  • &tvFilters =`featured==yes` There is even a working example of filtering getResources output by a TemplateVariable

Snippet Example

<h3>Output:</h3>
<div class="row-fluid">
[[refreshChunkContents
?snippet=`getCompanyPrograms`
&chunkName=`displayCompanyPrograms`
&tpl=`tpl.CompanyPlan`]]
</div>

Snippet Explanation

&tpl=`tpl.CompanyPlan` To keep things consistent, I went with getResources's tpl property.

Even though my Snippet is far more complex than getResources, as it recognizes ACLs and pulls from APIs around the globe, the above is all that is needed to benefit from this wrapper as I do everything in the class.

Final Comments

I see little reason why this Wrapper will not work with getPage as far as the first page of results goes. Just include the Pagination content so the links can be created when the Snippet is ran via the Wrapper.

The subsequent links of getPage could then point to pages providing actual dynamic content through subsequent getPage calls on those pages.

In this article

    Get The Book

    Retailers:

    Amazon
    Kindle Edition

    MODX Revolution: Building the Web Your Way