PHPackages                             cpsit/typo3-cache-bags - 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. cpsit/typo3-cache-bags

ActiveTypo3-cms-extension[Caching](/categories/caching)

cpsit/typo3-cache-bags
======================

TYPO3 CMS extension to build and register cache bags for enhanced cache control

0.3.0(5mo ago)55.2k—0%[1 issues](https://github.com/CPS-IT/cache-bags/issues)[1 PRs](https://github.com/CPS-IT/cache-bags/pulls)GPL-2.0-or-laterPHPPHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0CI passing

Since Jun 26Pushed 1mo ago4 watchersCompare

[ Source](https://github.com/CPS-IT/cache-bags)[ Packagist](https://packagist.org/packages/cpsit/typo3-cache-bags)[ RSS](/packages/cpsit-typo3-cache-bags/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (8)Versions (8)Used By (0)

[![Extension icon](Resources/Public/Icons/Extension.svg)](Resources/Public/Icons/Extension.svg)

TYPO3 extension `cache_bags`
============================

[](#typo3-extension-cache_bags)

[![Coverage](https://camo.githubusercontent.com/56371fbbe392ffa6fc116ede72f3410f03636cf41065450bd977c77d2214ff68/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c73436f7665726167652f6769746875622f4350532d49542f63616368652d626167733f6c6f676f3d636f766572616c6c73)](https://coveralls.io/github/CPS-IT/cache-bags)[![CGL](https://github.com/CPS-IT/cache-bags/actions/workflows/cgl.yaml/badge.svg)](https://github.com/CPS-IT/cache-bags/actions/workflows/cgl.yaml)[![Release](https://github.com/CPS-IT/cache-bags/actions/workflows/release.yaml/badge.svg)](https://github.com/CPS-IT/cache-bags/actions/workflows/release.yaml)[![License](https://camo.githubusercontent.com/68b128b315411e24aef998c3a1f5b0a21c4e522dfdadc522de45f645464782ac/687474703a2f2f706f7365722e707567782e6f72672f63707369742f7479706f332d63616368652d626167732f6c6963656e7365)](LICENSE.md)
[![Version](https://camo.githubusercontent.com/1b0c0b9ddcdc95625438ba371d333633e51480057726217539eb6732b52ede58/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f63616368655f626167732f76657273696f6e2f736869656c6473)](https://extensions.typo3.org/extension/cache_bags)[![Downloads](https://camo.githubusercontent.com/5ed4fecc73f18c70e88555660484aafc088a6243906904b6681e531eb6dc6721/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f63616368655f626167732f646f776e6c6f6164732f736869656c6473)](https://extensions.typo3.org/extension/cache_bags)[![Supported TYPO3 versions](https://camo.githubusercontent.com/1903e1b7161c8756246a9d6c936e050ad1537d4d3b046bd9638031d72413bd15/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f63616368655f626167732f7479706f332f736869656c6473)](https://extensions.typo3.org/extension/cache_bags)[![Extension stability](https://camo.githubusercontent.com/361e924b409064868efc8126d1109e3542f6d30a42ba21413f373591428364ee/68747470733a2f2f736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f7479706f332d6261646765732e6465762f62616467652f63616368655f626167732f73746162696c6974792f736869656c6473)](https://extensions.typo3.org/extension/cache_bags)

📦 [Packagist](https://packagist.org/packages/cpsit/typo3-cache-bags) | 🐥 [TYPO3 extension repository](https://extensions.typo3.org/extension/cache_bags) | 💾 [Repository](https://github.com/CPS-IT/cache-bags) | 🐛 [Issue tracker](https://github.com/CPS-IT/cache-bags/issues)

---

An extension for TYPO3 CMS to build and register *cache bags* for enhanced cache control. Cache bags are built during runtime on uncached contents and can be used to define cache metadata like cache tags. In addition, they are used to calculate expiration dates for specific cache entries. This allows are fine-grained cache control, depending on the contents and their explicit dependencies like specific database contents or short-living API requests.

🚀 Features
----------

[](#-features)

- Interface for cache bags with different cache scopes (e.g. pages)
- Cache bag registry to handle generated cache bags
- Cache expiration calculator for various use cases (query builder, query result etc.)
- Event listener to override page cache expiration, based on registered page cache bags
- Compatible with TYPO3 13.4 LTS

🔥 Installation
--------------

[](#-installation)

### Composer

[](#composer)

```
composer require cpsit/typo3-cache-bags
```

### TER

[](#ter)

Alternatively, you can download the extension via the [TYPO3 extension repository (TER)](https://extensions.typo3.org/extension/cache_bags).

⚡ Usage
-------

[](#-usage)

### Cache bags

[](#cache-bags)

A *cache bag* can be seen as some type of metadata collection for a specific cache scope, e.g. for the current page (Frontend-related cache). It is used to control the cache behavior within a given scope, for example by defining custom cache tags or an explicit expiration date.

At the moment the following cache bags are supported:

Cache bagScope[`Cache\Bag\PageCacheBag`](Classes/Cache/Bag/PageCacheBag.php)[`Enum\CacheScope::Pages`](Classes/Enum/CacheScope.php)Tip

You can also add your own cache bags by implementing [`Cache\Bag\CacheBag`](Classes/Cache/Bag/CacheBag.php).

Here is an example about how to generate a new `PageCacheBag` for a given page:

```
use CPSIT\Typo3CacheBags;

$pageId = 72;
$expirationDate = new DateTimeImmutable('tomorrow midnight');

$cacheBag = Typo3CacheBags\Cache\Bag\PageCacheBag::forPage($pageId, $expirationDate);
```

### Cache bag registry

[](#cache-bag-registry)

In order to actually use a generated cache bag, each bag must be registered in the global [`Cache\Bag\CacheBagRegistry`](Classes/Cache/Bag/CacheBagRegistry.php). This registry is defined as singleton instance and stores all registered cache bags during runtime.

The `CacheBagRegistry` should be injected using dependency injection or, if DI is not possible, by using `GeneralUtility::makeInstance()`:

```
use CPSIT\Typo3CacheBags;
use TYPO3\CMS\Core;

$cacheBag = Typo3CacheBags\Cache\Bag\PageCacheBag::forPage(72);
$cacheBagRegistry = Core\Utility\GeneralUtility::makeInstance(Typo3CacheBags\Cache\Bag\CacheBagRegistry::class);
$cacheBagRegistry->add($cacheBag);
```

#### Dispatched events

[](#dispatched-events)

When adding a new `CacheBag` to the registry, a [`CacheBagRegisteredEvent`](Classes/Event/CacheBagRegisteredEvent.php) is dispatched. It is used, for example, to apply cache tags to the current Frontend request (using the shipped [`PageCacheBagRegisteredEventListener`](Classes/EventListener/PageCacheBagRegisteredEventListener.php)).

#### Get closest expiration date

[](#get-closest-expiration-date)

Based on all registered cache bags, the registry is able to calculate the closest expiration date (if any cache bag provides an expiration date) for a given cache scope:

```
use CPSIT\Typo3CacheBags;
use TYPO3\CMS\Core;

$cacheBagRegistry = Core\Utility\GeneralUtility::makeInstance(Typo3CacheBags\Cache\Bag\CacheBagRegistry::class);
$expirationDate = $cacheBagRegistry->getExpirationDate(Typo3CacheBags\Enum\CacheScope::Pages);
```

This is used, for example, to apply the expiration date to the current Frontend page cache (using the shipped [`PageCacheLifetimeEventListener`](Classes/EventListener/PageCacheLifetimeEventListener.php)for TYPO3 ≥ v12 and [`PageCacheTimeoutHook`](Classes/Hooks/PageCacheTimeoutHook.php)for TYPO3 v11).

### Cache expiration calculator

[](#cache-expiration-calculator)

As already mentioned, cache bags may also store the expiration date of a targeted cache entry. The extension ships with a [`Cache\CacheExpirationCalculator`](Classes/Cache/Expiration/CacheExpirationCalculator.php)that can be used to calculate an expiration date. The calculation is based on various input methods. At the moment, the following methods are available:

- Calculation based on an **Extbase query or query result**
- Calculation based on a **Query Builder** instance
- Calculation based on an initialized **Relation Handler**

```
use CPSIT\Typo3CacheBags;
use TYPO3\CMS\Core;

// Use DI instead, calculator is *NOT* publicly available in the service container!
$cacheExpirationCalculator = Core\Utility\GeneralUtility::makeInstance(Typo3CacheBags\Cache\Expiration\CacheExpirationCalculator::class);
$connectionPool = Core\Utility\GeneralUtility::makeInstance(Core\Database\ConnectionPool::class);

$queryBuilder = $connectionPool->getQueryBuilderForTable('pages');
$queryBuilder->select('*')
    ->from('pages')
    ->where(
        $queryBuilder->expr()->or(
            $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter(72, Core\Database\Connection::PARAM_INT)),
            $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(72, Core\Database\Connection::PARAM_INT)),
        ),
    )
;

$expirationDate = $cacheExpirationCalculator->forQueryBuilder('pages', $queryBuilder);
$cacheBag = Typo3CacheBags\Cache\Bag\PageCacheBag::forPage(72, $expirationDate);
```

### Full example

[](#full-example)

Typical use cases of cache bags are list and detail views of custom records in Frontend scope. Here is a full example about how to use the `PageCacheBag`in list and detail views of a custom table:

```
use CPSIT\Typo3CacheBags;
use Psr\Http\Message;
use TYPO3\CMS\Core;
use TYPO3\CMS\Extbase;

final class BlogController extends Extbase\Mvc\Controller\ActionController
{
    public function __construct(
        private readonly BlogRepository $blogRepository,
        private readonly Typo3CacheBags\Cache\Bag\CacheBagRegistry $cacheBagRegistry,
        private readonly Typo3CacheBags\Cache\Expiration\CacheExpirationCalculator $cacheExpirationCalculator,
    ) {}

    public function listAction(): Message\ResponseInterface
    {
        /** @var Extbase\Persistence\QueryResultInterface $blogArticles */
        $blogArticles = $this->blogRepository->findAll();

        // Create cache bag with reference to the queried table
        // and apply the calculated expiration date of all queried blog articles
        $cacheBag = Typo3CacheBags\Cache\Bag\PageCacheBag::forTable(
            Blog::TABLE_NAME,
            $this->cacheExpirationCalculator->forQueryResult(Blog::TABLE_NAME, $blogArticles),
        );

        // Add cache bag to registry
        $this->cacheBagRegistry->add($cacheBag);

        $this->view->assign('articles', $blogArticles);

        return $this->htmlResponse();
    }

    public function detailAction(Blog $article): Message\ResponseInterface
    {
        // Create cache bag with reference to the current article
        // and apply the article's endtime as cache expiration date
        $cacheBag = Typo3CacheBags\Cache\Bag\PageCacheBag::forRecord(
            Blog::TABLE_NAME,
            $article->getUid(),
            $article->getEndtime(),
        );

        // Add cache bag to registry
        $this->cacheBagRegistry->add($cacheBag);

        $this->view->assign('article', $article);

        return $this->htmlResponse();
    }
}
```

🧑‍💻 Contributing
----------------

[](#‍-contributing)

Please have a look at [`CONTRIBUTING.md`](CONTRIBUTING.md).

💎 Credits
---------

[](#-credits)

The extension icon ("container") is a modified version of the original [`actions-container`](https://typo3.github.io/TYPO3.Icons/icons/actions/actions-container.html) icon from TYPO3 core which is originally licensed under [MIT License](https://github.com/TYPO3/TYPO3.Icons/blob/main/LICENSE).

⭐ License
---------

[](#-license)

This project is licensed under [GNU General Public License 2.0 (or later)](LICENSE.md).

###  Health Score

44

—

FairBetter than 92% of packages

Maintenance77

Regular maintenance activity

Popularity26

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 79.4% 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 ~257 days

Total

3

Last Release

175d ago

PHP version history (3 changes)0.1.0PHP ~8.1.0 || ~8.2.0 || ~8.3.0

0.2.0PHP ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0

0.3.0PHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/144cefe55242b883c87cb537463f3ba75a0f8198fc5b602b50c838aae31fe7ee?d=identicon)[eliashaeussler](/maintainers/eliashaeussler)

![](https://www.gravatar.com/avatar/a664c83f7a6760600d2a325f751b2a206f686b3dcb2f1dce5655ead343dc5a24?d=identicon)[cps](/maintainers/cps)

---

Top Contributors

[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (158 commits)")[![eliashaeussler](https://avatars.githubusercontent.com/u/16313625?v=4)](https://github.com/eliashaeussler "eliashaeussler (41 commits)")

---

Tags

cachecmsexpiration-dateextensiontypo3

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cpsit-typo3-cache-bags/health.svg)

```
[![Health](https://phpackages.com/badges/cpsit-typo3-cache-bags/health.svg)](https://phpackages.com/packages/cpsit-typo3-cache-bags)
```

###  Alternatives

[predis/predis

A flexible and feature-complete Redis/Valkey client for PHP.

7.8k305.7M2.4k](/packages/predis-predis)[eliashaeussler/typo3-warming

Warming - Warms up Frontend caches based on an XML sitemap. Cache warmup can be triggered via TYPO3 backend or using a console command. Supports multiple languages and custom crawler implementations.

20229.9k](/packages/eliashaeussler-typo3-warming)[eliashaeussler/typo3-form-consent

Extension for TYPO3 CMS that adds double opt-in functionality to EXT:form

1481.0k](/packages/eliashaeussler-typo3-form-consent)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[eliashaeussler/cache-warmup

Composer package to warm up website caches, based on a given XML sitemap

73387.5k5](/packages/eliashaeussler-cache-warmup)[pagemachine/typo3-formlog

Form log for TYPO3

23225.3k6](/packages/pagemachine-typo3-formlog)

PHPackages © 2026

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