In Part 5 of this series, we introduced the template cache with a quick example that showed how to cache page fragments. As we mentioned then, the template cache can be used to cache page fragments as well as entire web pages. This post is broken up into three sections that explore the three typical use cases of the template cache: Caching entire wen pages, caching entire web pages with url parameters and caching page fragments.

Caching Entire Web Pages

To cache an entire web page, simply place a single cfcache tag at the top of you page. Here's an example:


<cfcache action="serverCache">

I'm some text on a page<br />

<cfoutput>
I'm dynamic. The time is currently #timeFormat(now(),'hh:mm:ss')# <br />
</cfoutput>

I'm some more test on a page

With an open cfcache tag at the beginning of the page, this code tells ColdFusion to go ahead and write the entire page to the template cache. If you haven't modified your cache configuration from the default ColdFusion install, this item will live in the cache for 24 hours (86400 seconds) unless you restart your JVM by restarting your ColdFusion server or you manually flush the cache first, which you can do by using the cfcache tag with action="flush" which we'll talk about in the next part of this series.

As I mentioned in Part 5 of this series, the ColdFusion template cache acts as a black box. You don't really get to see how it magically does gets and puts of your content or how it generates keys for the data going into the cache. What I didn't mention before is that there's an undocumented function in ColdFusion 9.0 called getAllTemplateCacheIDs() that will show you all of the keys for items that ColdFusion puts in the template cache. There isn't really a lot you can do with this information since neither the cfcache tag nor any of the cache functions allow you to specify a key for items in the template cache. However, the function is useful for showing how ColdFusion handles general ColdFusion pages, pages with URL parameters and page fragments differently within the cache.

When ColdFusion takes a regular old ColdFusion page and caches it in the template cache, it generates a unique key for it based on the URL and a UUID appended to it. Here's an example of a file called cache_entire_page.cfm:


<cfcache action="serverCache">

<cfoutput>
I'm dynamic. The time is currently #timeFormat(now(),'hh:mm:ss')# </cfoutput>

If you run this page, ColdFusion puts it in the template cache as you would expect. To see the key that ColdFusion automatically generates for it, create a new ColdFusion page with this code in it:


<cfdump var="#getAllTemplateCacheIds()#">

If you run that newly created page, you should see a dump of all the keys in the template cache for your application. It should look something like this:

Caching Pages with Unique URLs

By default, URL parameters for ColdFusion pages stored in the template cache are ignored. If you want to see this in action, try adding ?id=10 to the URL of the cache_entire_page.cfm file we used for our previous example. After you've added the URL parameter and reloaded the page, go ahead and dump the contents of the template cache again. What you'll notice is that it contains the same exact key as the page without the URL parameter. Obviously this isn't good if your application has what it considers to be unique pages that need to be cached individually based on URL parameters. Luckily, the cfcache tag gives you a way to handle this. All you need to do is add useQueryString="true" to your cfcache tag and that will tell ColdFusion to treat pages that have URL parameters as unique pages when it caches them. Go ahead and save this code as a new ColdFusion page:


<cfparam name="URL.productID" default="0">

<cfcache action="serverCache" usequerystring="true">
<cfoutput>
Welcome to the page for product ID #URL.productID#<br />
Timestamp: #timeFormat(now(), 'hh:mm:ss')#
</cfoutput>

Now try calling this page with no URL parameter passed to it. Right after you've done that, append ?productID=55 to the URL and call it again. Once you've done this, run the sump of all the keys in the template cache and you should have output that looks like this:

What you should notice right away is that there are now two new keys being returned for the page you just called twice. The first key looks just like the key from our last example. It contains just the template name and a UUID. The other key, however, contains something new. In addition to the URL for the template and the appended UUID, it also contains the query string as part of the key name. As you can see, by using the useQueryString parameter of the cfcache tag, we've instructed ColdFusion to treat pages with URL parameters as unique when it places them in the template cache.

Caching Page Fragments

When ColdFusion caches a page fragment, it uses a combination of the page's file name as well as the position of the actual code block that's surrounded by cfcache tags in your ColdFusion file. Each page fragments gets its own entry in the cache since fragments can be independently expired or flushed from the cache. Consider the following example:

This is a fragment

And so is this #now()#

If you execute this, you'll get some output as well as a dump of all of the cached items in the template cache. At this point, there are two items in the cache:

Now say you weren't happy that the two lines of output on your page were all run together and you wanted to put a line break between each one. You might modify your code and add in a simple paragraph tag or line break like so:


<cfcache>
This is a fragment
</cfcache>

<p>

<cfcache>
<cfoutput>
And so is this #now()#
</cfoutput>
</cfcache>

<cfdump var="#getalltemplatecacheids()#">

Go ahead and run the code once you've inserted the

tag. What you'll now see is that you have three items in the cache:

What's happening is that ColdFusion is using the position of the code in your page as part of the ID for the cached item. When you inserted the

tag, the position of the fragment you cached also changed by moving down a few lines, and ColdFusion assumed you had added a new page fragment that you wanted to cache.

This may or may not be a big deal to people as CF will still pull the correct cached item every time. The gotcha is that if you have a lot of caching going on, and you're making a lot of changes in a development environment, it's possible to fill your cache up with a lot of junk pretty quickly – just something to be aware of with the template cache when working with page fragments.

Now that we've covered the basics of the template cache, keep an eye out for my next post where I'll cover the ins and outs of updating items in the template cache including techniques for time based expiry, cache flushing, and dependent caching.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Aaron West's Gravatar Rob, great post as always. I wanted to let you know it looks like a tag isn't closed in your posts code. At one point sample code is shown and the formatting stays the same until the end of the post.
# Posted By Aaron West | 12/6/09 11:49 AM



Copyright 1995-2010 Rob Brooks-Bilson. All rights reserved.
Aura skin for Raymond Camden's BlogCFC inspired by Joe Rinehart & Steven Erat. This blog is running version 5.9.004.