PHPackages                             generoi/sage-cachetags - 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. generoi/sage-cachetags

ActiveLibrary[Caching](/categories/caching)

generoi/sage-cachetags
======================

v2.4.0(1mo ago)927.7k↓13.4%1[1 issues](https://github.com/generoi/sage-cachetags/issues)MITPHPPHP &gt;=8.2

Since Jul 29Pushed 2mo ago4 watchersCompare

[ Source](https://github.com/generoi/sage-cachetags)[ Packagist](https://packagist.org/packages/generoi/sage-cachetags)[ Docs](https://github.com/generoi/sage-cachetags)[ RSS](/packages/generoi-sage-cachetags/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (2)Versions (12)Used By (0)

sage-cachetags
==============

[](#sage-cachetags)

A sage package for tracking what data rendered pages rely on using Cache Tags (inspired by [Drupal's Cache Tags](https://www.drupal.org/docs/drupal-apis/cache-api/cache-tags)).

Example
-------

[](#example)

Front page displays the page content as well as 3 recipe previews. The cache tags might be:

- `post:1` for the front page
- `post:232`, `post:233`, `post:234` for the 3 recipe previews
- `term:123`, `term:124` for a recipe category shown in the recipe previews
- `post:10` for a product name featured in one of the 3 recipes.

This set of tags will be gathered while rendering the page and then stored in the database and optionally added as a HTTP header.

When any of the posts or terms are updated, page caches and reverse proxies know that the front page cache should be cleared.

Installation
------------

[](#installation)

### Composer

[](#composer)

```
composer require generoi/sage-cachetags
```

### Plugin

[](#plugin)

Download the zip, install like a regular plugin, then follow the [standalone installation](#standalone-without-acorn) instructions below.

### With Acorn (Sage theme)

[](#with-acorn-sage-theme)

Start by publishing the config/cachetags.php configuration file using Acorn:

```
wp acorn vendor:publish --provider="Genero\Sage\CacheTags\CacheTagsServiceProvider"
```

Edit it to your liking and if you're using the database store, scaffold the required database table:

```
wp acorn cachetags:database
```

### Standalone (without Acorn)

[](#standalone-without-acorn)

For WordPress sites without Acorn, use the `Bootstrap` class in your theme's `functions.php` or a mu-plugin. The `Bootstrap` class provides a fluent interface for configuration:

```
use Genero\Sage\CacheTags\Bootstrap;
use Genero\Sage\CacheTags\Actions\Core;
use Genero\Sage\CacheTags\Actions\HttpHeader;
use Genero\Sage\CacheTags\Invalidators\SuperCacheInvalidator;
use Genero\Sage\CacheTags\Stores\WordpressDbStore;

// Bootstrap CacheTags using fluent interface
(new Bootstrap())
    ->store(WordpressDbStore::class)
    ->invalidators([SuperCacheInvalidator::class])
    ->actions([Core::class, HttpHeader::class])
    ->debug(defined('WP_DEBUG') && WP_DEBUG)
    ->httpHeader('Cache-Tag')
    ->bootstrap();
```

If you're using the database store, scaffold the required database table using WP-CLI:

```
wp cachetags database
```

Invalidators
------------

[](#invalidators)

Currently it supports Kinsta Page Cache, WP Super Cache, SiteGround Optimizer and Fastly. You can use multiple invalidators if you eg use Fastly in front of Kinsta and want to invalidate both.

### SiteGround Optimizer

[](#siteground-optimizer)

Integration exists if you add the `SiteGroundCacheInvalidator` invalidator in the `config/cachetags.php` file.

### Super Cache

[](#super-cache)

Integration exists if you add the `SuperCacheInvalidator` invalidator in the `config/cachetags.php` file.

### Kinsta

[](#kinsta)

Integration exists if you add the `KinstaCacheInvalidator` in the `config/cachetags.php` file.

### Cloudflare

[](#cloudflare)

Cloudflare Pro plan supports [HTTP header purging](https://blog.cloudflare.com/introducing-a-powerful-way-to-purge-cache-on-cloudflare-purge-by-cache-tag/) but an invalidor doesn't exist at the moment. If you're up for it, take a look at the Fastly one as an example.

### Fastly

[](#fastly)

There's both a `FastlySoftCacheInvalidator` and a `FastlyCacheInvalidator` (hard) cache invalidator for Fastly (Varnish) proxy cache. Using this set up you do not need a persistent `store` since Fastly works with HTTP headers. Example `config/cachetags.php`

```
$isProduction = in_array(parse_url(WP_HOME, PHP_URL_HOST), [
    'www.example.com',
]);

return [
    'http-header' => 'Surrogate-Key',
    'store' => CacheTagStore::class,
    'invalidator' => array_filter([
        $isProduction ? FastlySoftCacheInvalidator::class : null,
    ]),
    'action' => [
        Core::class,
        HttpHeader::class,
    ],
];
```

Traits for use with roots/sage
------------------------------

[](#traits-for-use-with-rootssage)

### Composers

[](#composers)

```
namespace App\View\Composers;

use Genero\Sage\CacheTags\Concerns\ComposerCacheTags;
use Genero\Sage\CacheTags\Tags\CoreTags;
use Roots\Acorn\View\Composer;
use Illuminate\View\View;

class ContentSingle extends Composer
{
    use ComposerCacheTags;

    protected static $views = [
        'partials.content-single',
    ];

    /**
     * @return array
     */
    public function with()
    {
        $post = get_post();

        return [
            'post' => $post,
            'date' => $this->date($post),
            'authors' => $this->authors($post),
            'excerpt' => $this->excerpt($post),
            'related' => $this->related($post),
            'categories' => $this->categories($post),
        ];
    }

    public function cacheTags(View $view): array
    {
        return [
            ...CoreTags::posts($view->post),
            ...CoreTags::terms($view->categories),
            ...CoreTags::query($this->related())
        ];
    }
}
```

### ACF Blocks

[](#acf-blocks)

```
namespace App\Blocks;

use Genero\Sage\CacheTags\Tags\CoreTags;
use Genero\Sage\CacheTags\Concerns\BlockCacheTags;

class ArticleList extends Block
{
    use BlockCacheTags;

    public $name = 'Article List';
    public $slug = 'article-list';

    public function cacheTags(): array
    {
        $query = $this->buildQuery();

        return [
            ...CoreTags::archive('post'),
            ...CoreTags::query($query),
        ];
    }
}
```

CLI
---

[](#cli)

**With Acorn:**

```
# Flush the entire cache
wp acorn cachetags:flush

# Scaffold database table
wp acorn cachetags:database
```

**Standalone:**

```
# Flush the entire cache
wp cachetags flush

# Scaffold database table
wp cachetags database
```

API
---

[](#api)

### Accessing CacheTags instance

[](#accessing-cachetags-instance)

**With Acorn:**

```
use Genero\Sage\CacheTags\CacheTags;

// Get instance from container
$cacheTags = app(CacheTags::class);
```

**Standalone:**

```
use Genero\Sage\CacheTags\CacheTags;

// Get the singleton instance
$cacheTags = CacheTags::getInstance();
```

### Create a custom tag

[](#create-a-custom-tag)

The nicest way is to look at the code of this repo and create a custom `Action` and maybe a `CustomTag` class that you use, but the logic is really nothing more than:

**With Acorn:**

```
use Genero\Sage\CacheTags\CacheTags;

// Tag content
app(CacheTags::class)->add(['custom-tag']);

// Clear it whenever you want
\add_action('custom/update', fn() => app(CacheTags::class)->clear(['custom-tag']));
```

**Standalone:**

```
use Genero\Sage\CacheTags\CacheTags;

// Tag content
CacheTags::getInstance()?->add(['custom-tag']);

// Clear it whenever you want
\add_action('custom/update', fn() => CacheTags::getInstance()?->clear(['custom-tag']));
```

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance84

Actively maintained with recent releases

Popularity35

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity63

Established project with proven stability

 Bus Factor1

Top contributor holds 95.1% 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 ~96 days

Recently: every ~10 days

Total

11

Last Release

55d ago

Major Versions

v1.3.0 → v2.0.02026-02-11

PHP version history (2 changes)v1.0.0PHP &gt;=7.4

v2.0.0PHP &gt;=8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/302736?v=4)[oxyc](/maintainers/oxyc)[@oxyc](https://github.com/oxyc)

---

Top Contributors

[![oxyc](https://avatars.githubusercontent.com/u/302736?v=4)](https://github.com/oxyc "oxyc (58 commits)")[![thunderdw](https://avatars.githubusercontent.com/u/85177135?v=4)](https://github.com/thunderdw "thunderdw (2 commits)")[![toffebjorkskog](https://avatars.githubusercontent.com/u/1155260?v=4)](https://github.com/toffebjorkskog "toffebjorkskog (1 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/generoi-sage-cachetags/health.svg)

```
[![Health](https://phpackages.com/badges/generoi-sage-cachetags/health.svg)](https://phpackages.com/packages/generoi-sage-cachetags)
```

###  Alternatives

[react/cache

Async, Promise-based cache interface for ReactPHP

444112.4M40](/packages/react-cache)[wp-media/wp-rocket

Performance optimization plugin for WordPress

7431.3M3](/packages/wp-media-wp-rocket)[illuminate/cache

The Illuminate Cache package.

12835.6M1.4k](/packages/illuminate-cache)[colinmollenhour/php-redis-session-abstract

A Redis-based session handler with optimistic locking

6325.6M14](/packages/colinmollenhour-php-redis-session-abstract)[cheprasov/php-redis-client

Php client for Redis. It is a fast, fully-functional and user-friendly client for Redis, optimized for performance. RedisClient supports the latest versions of Redis starting from 2.6 to 6.0

1281.2M21](/packages/cheprasov-php-redis-client)[amphp/redis

Efficient asynchronous communication with Redis servers, enabling scalable and responsive data storage and retrieval.

165634.7k44](/packages/amphp-redis)

PHPackages © 2026

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