Add Caching to the Navigation

Finally, let’s add some caching to the header navigation item. We don’t have to add caching now, but as our site gets bigger and bigger the PageList class may have a more difficult time of retrieving pages on every page load. Additionally, it’s just not necessary to run this query in a dynamic way on every page load. The navigation just isn’t going to be changing that much!

So let’s cache the result of our getResults() call. We’ll keep the logic that checks the current page and applies the classes, we’ll just cut down on the potentially costly database queries. Add these lines of code:

Let’s walk through this code. Before we instantiate the PageList object, we create a copy of the Concrete CMS Expensive cache. The Expensive cache is so-named because it stores things that require a potentially large amount of time to process. It stores this data in a relatively slow place -- your web hosting filesystem -- by default, so it’s important to only use this for data that’s potentially pretty slow. But the upside of storing this data here is that it’s persistent and cacheable.

Once we have an instance of our Cache object, let’s try to retrieve something from it. I’ve named this key header_navigation_pages. It can be anything as long as it’s not reused elsewhere, because that would lead to collisions. Next, we check to see if there’s something in our cache with this key, with the isMiss() method. If there’s a miss, it means that there’s nothing in that cache with this key, meaning we need to run the original code as before.

After we run the original code, but before we loop through the results array and display the pages in the header, we set those results in our cache item, and set a time in seconds for it to expire after. I’ve chosen two hours. Manually clearing your Concrete cache via the Dashboard will also manually purge this entry and all others from the cache. (This can be useful to force a header navigation update in the event that a new page has been added to the site.) Finally, we save the item in the cache.

Next, we get the else section of our isMiss() call. This is the code that runs if something is found in the cache. In that case, we retrieve it from the item using get().

In both cases we now have our original array of $results objects, which we can loop through and display in the header. But we can rest easier knowing that our site is going to be a little bit more performant, and a little bit better prepared for the future.