PHPackages                             weboftalent/cachekeyhelper - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. weboftalent/cachekeyhelper

ActiveSilverstripe-vendormodule[Caching](/categories/caching)

weboftalent/cachekeyhelper
==========================

Centralise partial queries into a single query to improve performance

2.0.2(7y ago)101061[1 issues](https://github.com/gordonbanderson/weboftalent-cachekey-helper/issues)MITPHPPHP ~5.6|~7.0

Since Jan 18Pushed 4y ago1 watchersCompare

[ Source](https://github.com/gordonbanderson/weboftalent-cachekey-helper)[ Packagist](https://packagist.org/packages/weboftalent/cachekeyhelper)[ RSS](/packages/weboftalent-cachekeyhelper/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (3)Versions (12)Used By (0)

Introduction
============

[](#introduction)

[![Build Status](https://github.com/gordonbanderson/weboftalent-cachekey-helper/actions/workflows/ci.yml/badge.svg)](https://github.com/gordonbanderson/weboftalent-cachekey-helper/actions/workflows/ci.yml)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/94c3d1d3464df9e0dda31979f9cd8948a2da8f286741c4fd4a3b0937edb7d64c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f676f72646f6e62616e646572736f6e2f7765626f6674616c656e742d63616368656b65792d68656c7065722f6261646765732f7175616c6974792d73636f72652e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/gordonbanderson/weboftalent-cachekey-helper/?branch=main)[![Scrutinizer](https://camo.githubusercontent.com/8ca84372dbdbed4e7c65ec8ef6cb6ff2d7790f36639908aa045b3b48b91bfd7c/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f676f72646f6e62616e646572736f6e2f7765626f6674616c656e742d63616368656b65792d68656c7065722f6261646765732f6275696c642e706e673f623d6d61696e)](https://scrutinizer-ci.com/g/gordonbanderson/weboftalent-cachekey-helper/build-status/main)[![codecov.io](https://camo.githubusercontent.com/2ada904d37f8bc7ecc5acdc91b359bbc1e57fdf080484913b34a968b85e67f0b/68747470733a2f2f636f6465636f762e696f2f6769746875622f676f72646f6e62616e646572736f6e2f7765626f6674616c656e742d63616368656b65792d68656c7065722f636f7665726167652e7376673f6272616e63683d6d61696e)](https://codecov.io/github/gordonbanderson/weboftalent-cachekey-helper?branch=main)

[![Latest Stable Version](https://camo.githubusercontent.com/0975c0814b7d47b56f41a6e5db8530c90cbfed857aa99ca86f84d7d3dfe7e58e/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f76657273696f6e)](https://packagist.org/packages/weboftalent/cachekeyhelper)[![Latest Unstable Version](https://camo.githubusercontent.com/3429455713711d74b9855d09178650304b130420db3b49121a40ff03309bf172/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f762f756e737461626c65)](//packagist.org/packages/weboftalent/cachekeyhelper)[![Total Downloads](https://camo.githubusercontent.com/060d7a6ca55047efc67068b08c198a6d350d0e87205894123f0f12ecce8138d5/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f646f776e6c6f616473)](https://packagist.org/packages/weboftalent/cachekeyhelper)[![License](https://camo.githubusercontent.com/eda529081394978f640f2e55ce11d0f1bb5a43cabf972d1ffca99863c86db483/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f6c6963656e7365)](https://packagist.org/packages/weboftalent/cachekeyhelper)[![Monthly Downloads](https://camo.githubusercontent.com/21d895a62fd45e1febadb95b7985486634689e21dcd46ec2b1fc00d693d8fd10/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f642f6d6f6e74686c79)](https://packagist.org/packages/weboftalent/cachekeyhelper)[![Daily Downloads](https://camo.githubusercontent.com/aabe2363005d44b520ca934aadda8c4b20a6836d25edbb23b08ad4bd9866af4a/68747470733a2f2f706f7365722e707567782e6f72672f7765626f6674616c656e742f63616368656b657968656c7065722f642f6461696c79)](https://packagist.org/packages/weboftalent/cachekeyhelper)

[![codecov.io](https://camo.githubusercontent.com/b87ebb540ab7f9fe28479a583677ec854e52f42dd6126b8f344ff3f11e8dc8e4/68747470733a2f2f636f6465636f762e696f2f6769746875622f676f72646f6e62616e646572736f6e2f7765626f6674616c656e742d63616368656b65792d68656c7065722f6272616e63682e7376673f6272616e63683d6d61696e)](https://camo.githubusercontent.com/b87ebb540ab7f9fe28479a583677ec854e52f42dd6126b8f344ff3f11e8dc8e4/68747470733a2f2f636f6465636f762e696f2f6769746875622f676f72646f6e62616e646572736f6e2f7765626f6674616c656e742d63616368656b65792d68656c7065722f6272616e63682e7376673f6272616e63683d6d61696e)

In order to improve the performance of a SilverStripe site it is very useful to use partial caching to cache fragments of a page against a given condition, usually either a LastEdited field or something of periodic time, e.g. caching a copy of a twitter feed on a site and updating it every 5 minutes. When an item is edited the LastEdited date is updated, or when the period of time elapses the cache is 'busted' and the partial fragement on the page is updated with the new rendering.
Whilst this technique works it still requires a hit against the database for each partially cached fragement of a page. So why not get them all in a single query?

Technique
=========

[](#technique)

When fine tuning a site it is useful to trace SQL activity as follows. Add a trace error\_log statement in the query() method of MySQLDatabase.php as follows:

```
	public function query($sql, $errorLevel = E_USER_ERROR) {
		error_log('SQL:'.$sql);

```

One can then observe SQL trace using a command similar to the following:

```
	tail -f /var/log/apache2/yoursite.silverstripe.errors.log | grep SQL

```

This is useful when trying to identify areas of the site where queries are being generated. To get a purely numberic value of the number of SQL statements being executed, use a variant of the following:

```
	watch -n 1 'cat /var/log/apache2/yoursite.silverstripe.errors.log | grep SQL | wc -l'

```

Every time a page is loaded, the number of cumulative SQL statements executed will be shown in a terminal window. One needs to do a bit of maths, but it's indicative of whether your dealing with 10s of queries, hundreds of queries or indeed thousands of them.

Installation
============

[](#installation)

SilverStripe 4
--------------

[](#silverstripe-4)

```
composer require "weboftalent/cachekeyhelper:^2"
```

SilverStripe 3
--------------

[](#silverstripe-3)

```
composer require "weboftalent/cachekeyhelper:^1"
```

Usage
=====

[](#usage)

Configuration
-------------

[](#configuration)

For any classes that one wishes to cache on a page, and the configuration is slightly different for Pages (that extend SiteTree) and non SiteTree objects.

Create a file in \_config/ of your site or module, called for example cachekeys.yml By default, Page,Member, and Group already have their most recent LastEdited dates obtained.
If we for example have a class called Article that extends Page, and that Article has Links which extend DataObject then the configuration would look like this:

```
CacheKeyHelper:
  SilverStripe\CMS\Model\SiteTree:
    Article
  SilverStripe\CMS\Model\SiteTree:
    - WebOfTalent\Link\Link

```

Remember that a /dev/build is required for any configuration changes to be effected.

Usage in Templates
------------------

[](#usage-in-templates)

### Caching Classes of Items

[](#caching-classes-of-items)

When creating a cache key, one can now use the following in a template:

```
$CacheKey('someprefix','YourClassName')

```

Imagine the scenario of a home page where we show the most recent Articles and Links. The template code for caching would look like this:

```

... render articles here ...

```

Similarly, the links would be cached thus:

```

... render latest links here ...

```

### Caching Current Page

[](#caching-current-page)

The current page is cached under CurrentPage

```

... render current page here ...

```

### Caching Child Folder Rendering

[](#caching-child-folder-rendering)

If one is rendering a folder of child items, a common enough idiom, the most recent child item LastEdited date is under the key ChildPage.

```

... render gallery of images here ...

```

### Caching Sibling Rendering

[](#caching-sibling-rendering)

When rendering a sidebar menu one normally renders a list of pages from the same folder, i.e. siblings. The relevant LastEdited value is stored under the key SiblingPage.

```

... render gallery of images here ...

```

### Caching Drop Down Menu

[](#caching-drop-down-menu)

For a drop down menu containing the top 2 levels of the SiteTree, one can use the cache key TopTwoLevels

```

... render gallery of images here ...

```

### SiteTree Last Edited

[](#sitetree-last-edited)

If one has a section of page that needs to be invalidated whenever anything is saved, use this key called SiteTree. An example of this would be a site map.

```

... rendering of sitemap here ...

```

### Site Configuration

[](#site-configuration)

Site configuration is cached under SiteConfig.

```

... $SiteConfig.TagLine ...

```

### Caching via Parameters

[](#caching-via-parameters)

In the case of search results it is useful to be able to cache by a URL parameter.

```

```

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~145 days

Recently: every ~217 days

Total

7

Last Release

2893d ago

Major Versions

1.0.0 → 3.1.x-dev2016-01-18

1.0.2 → 2.0.02018-05-06

### Community

Maintainers

![](https://www.gravatar.com/avatar/9af58f7ff675f65dbd2f20d39d8b80ed671eb0fe376eb978e497934c175196fe?d=identicon)[weboftalent](/maintainers/weboftalent)

---

Top Contributors

[![gordonbanderson](https://avatars.githubusercontent.com/u/7060?v=4)](https://github.com/gordonbanderson "gordonbanderson (59 commits)")

---

Tags

performancesilverstripecachingweboftalentpartials

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/weboftalent-cachekeyhelper/health.svg)

```
[![Health](https://phpackages.com/badges/weboftalent-cachekeyhelper/health.svg)](https://phpackages.com/packages/weboftalent-cachekeyhelper)
```

###  Alternatives

[silverstripe/staticpublishqueue

Static publishing queue to create static versions of pages for enhanced performance and security

45135.4k4](/packages/silverstripe-staticpublishqueue)[putyourlightson/craft-blitz

Intelligent static page caching for creating lightning-fast sites.

153471.5k29](/packages/putyourlightson-craft-blitz)[tractorcow/silverstripe-dynamiccache

FORK OF Silverstripe module for simple on the fly caching of dynamic content

3916.0k2](/packages/tractorcow-silverstripe-dynamiccache)[maartenstaa/laravel-41-route-caching

This package allows you to cache your routes definitions, thereby speeding up each request.

25371.9k](/packages/maartenstaa-laravel-41-route-caching)[alekseykorzun/memcached-wrapper-php

Optimized PHP 5 wrapper for Memcached extension that supports dog-piling, igbinary and local storage

2984.6k1](/packages/alekseykorzun-memcached-wrapper-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
