PHPackages                             ttempleton/craft-nocache - 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. ttempleton/craft-nocache

ActiveCraft-plugin

ttempleton/craft-nocache
========================

A Twig extension to escape caching inside cache blocks

3.1.0(3mo ago)4550.4k↓35.7%6[1 issues](https://github.com/ttempleton/craft-nocache/issues)[4 PRs](https://github.com/ttempleton/craft-nocache/pulls)1MITPHPPHP ^8.0.2CI failing

Since Mar 3Pushed 3mo ago2 watchersCompare

[ Source](https://github.com/ttempleton/craft-nocache)[ Packagist](https://packagist.org/packages/ttempleton/craft-nocache)[ RSS](/packages/ttempleton-craft-nocache/feed)WikiDiscussions 3.x Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (22)Used By (1)

No-Cache
========

[](#no-cache)

#### A [Craft CMS](http://craftcms.com) Twig extension that escapes caching inside cache blocks

[](#a-craft-cms-twig-extension-that-escapes-caching-inside-cache-blocks)

```
{% cache %}
    This will be cached
    {% nocache %}
        This won't be
    {% endnocache %}
{% endcache %}
```

It also works when disabling the cache from included files:

```
{% cache %}
    This will be cached
    {% include 'template' %}
{% endcache %}
```

*template.twig:*

```
{% nocache %}
    This won't be
{% endnocache %}
```

If you need to reference variables outside of the `nocache` tag, you will need to pass a context – much like how the `include` tag works when passing variables. Note that you do not have to pass global variables, such as `craft` or `currentUser`, but you will have to import your macros again.

```
{% set variable = 5 %}
{% nocache with {x: variable} %}
    The following value should be 5: {{ x }}
{% endnocache %}
```

Requirements
------------

[](#requirements)

No-Cache requires either Craft 5.9.0 or later versions of Craft 5, or Craft 4.17.0 or later versions of Craft 4.

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

[](#installation)

No-Cache can be installed from the [Craft Plugin Store](https://plugins.craftcms.com/) or with [Composer](https://packagist.org/).

### Craft Plugin Store

[](#craft-plugin-store)

Open your project's control panel, navigate to the Plugin Store, search for No-Cache and click Install.

### Composer

[](#composer)

Open your terminal, navigate to your project's root directory and run the following command:

```
composer require ttempleton/craft-nocache

```

Then open your project's control panel, navigate to Settings → Plugins, find No-Cache and click Install.

Example: User information
-------------------------

[](#example-user-information)

Say you have a list of products you want to show on your page. Under each product, you want an "add to cart" button. However, you only want to show this button *if* a user is logged in. Not only that, but you also want to disable the button if the user already has it in their cart. Unfortunately you're outputting 20 products a page with images, so caching the list seems like the responsible thing to do.

```
{% cache %}
{% for product in craft.entries().section('products').limit(20).all() %}

        {{ product.image.one().img }}
        {{ product.title }}
        {% if currentUser %}
             0 ? ' disabled' }}>Add to cart
        {% endif %}

{% endfor %}
{% endcache %}
```

Now we have a problem. The cache around the list of products will cause the `currentUser` logic to essentially not work, since they'll be cached along with the products. You can't isolate the user logic by separating things into multiple cache blocks, since you're in a loop, and the whole point was to cache the database call that grabs the product entries. So you either have to apply your user checking in Javascript (far from ideal), or disregard caching altogether.

With `nocache` tags you can fix this very easily:

```
{% cache %}
{% for product in craft.entries().section('products').limit(20).all() %}

        {{ product.image.one().img }}
        {{ product.title }}
        {% nocache with {productId: product.id} %}
        {% if currentUser %}
             0 ? ' disabled' }}>Add to cart
        {% endif %}
        {% endnocache %}

{% endfor %}
{% endcache %}
```

The `nocache` block will allow you to cache the entire product list, but still perform your user logic outside of the cache. It also allows passing of context, so you can still refer to products and entries inside the `nocache` block and access their properties, *without* any additional database calls.

Example: CSRF tokens
--------------------

[](#example-csrf-tokens)

A fantastic security feature, but one that basically renders caching impossible to use. Often you might find yourself outputting a form to the frontend, but it's nested deep within a stack of template includes and macros. At the top of this stack you've conveniently wrapped a cache tag around it.

Well, now your CSRF tokens are going to be cached and there's basically nothing you can do about it. Using `nocache` tags, this is no longer a problem:

```

    {% nocache %}{{ csrfInput() }}{% endnocache %}
    ...

```

Now you can include this form anywhere in your templates and not have to worry about your CSRF tokens being cached. As a side note, yes `nocache` tags *will* work even when they are not inside a cache block (though try and avoid doing this as `nocache` tags *do* add some overhead).

Caveat
------

[](#caveat)

Content inside `nocache` blocks will render slightly different than normal. Variables declared outside of the `nocache` block will actually have their values cached for the duration of the cache block.

This causes an issue in situations like the following:

```
{% set article = craft.entries().section('news').one() %}
{% cache %}
    ...
    {% nocache with {article: article} %}
        {{ article.title }}
    {% endnocache %}
{% endcache %}
```

You would expect that if you were to change the title of the article, it will update inside the `nocache` block. This is not the case, as the article itself would be cached due to the cache block.

There's a few ways around this. You could move the `{% set articles %}` statement *within* the cache block, so updating the article would cause the cache to bust. In situations where you are using the article inside the cache (but outside the `nocache` block) this is the preferred method, as you won't spend any database calls grabbing the article inside the `nocache` block.

```
{% cache %}
    {% set article = craft.entries().section('news').one() %}
    ...
    {% nocache with {article: article} %}
        {{ article.title }}
    {% endnocache %}
{% endcache %}
```

The other option is to query for the article inside the `nocache` block. This can be better than the above solution as updating the article title will not bust the cache. The difference in this situation is now the contents of the `nocache` block will cause a database call.

```
{% cache %}
    ...
    {% nocache %}
        {% set article = craft.entries().section('news').one() %}
        {{ article.title }}
    {% endnocache %}
{% endcache %}
```

Every situation will be different, so use your best judgement.

---

*Big thanks to [Ben Fleming](https://github.com/benjamminf) for creating No-Cache and for letting me take it over.*

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance80

Actively maintained with recent releases

Popularity41

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 54.8% 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 ~149 days

Recently: every ~186 days

Total

18

Last Release

100d ago

Major Versions

2.x-dev → 3.0.0-beta.12022-03-18

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/19421878?v=4)[Thomas Templeton](/maintainers/ttempleton)[@ttempleton](https://github.com/ttempleton)

---

Top Contributors

[![ttempleton](https://avatars.githubusercontent.com/u/19421878?v=4)](https://github.com/ttempleton "ttempleton (68 commits)")[![benjamminf](https://avatars.githubusercontent.com/u/6325915?v=4)](https://github.com/benjamminf "benjamminf (55 commits)")[![jaspertandy](https://avatars.githubusercontent.com/u/350834?v=4)](https://github.com/jaspertandy "jaspertandy (1 commits)")

---

Tags

cache-controlcraft-plugincraft2craft3craft4craftcmsplugincmscraftcms

### Embed Badge

![Health badge](/badges/ttempleton-craft-nocache/health.svg)

```
[![Health](https://phpackages.com/badges/ttempleton-craft-nocache/health.svg)](https://phpackages.com/packages/ttempleton-craft-nocache)
```

###  Alternatives

[spicyweb/craft-neo

A Matrix-like field type with block hierarchy

395798.1k10](/packages/spicyweb-craft-neo)[spicyweb/craft-embedded-assets

Manage YouTube videos, Instagram photos and more as first class assets

172435.6k9](/packages/spicyweb-craft-embedded-assets)[am-impact/amcommand

Command palette in Craft.

8674.1k3](/packages/am-impact-amcommand)[spicyweb/craft-quick-field

Create Craft CMS fields on the fly while designing field layouts

10432.9k](/packages/spicyweb-craft-quick-field)[putyourlightson/craft-log-to-file

Logs messages to a specific log file for Craft CMS.

29368.0k5](/packages/putyourlightson-craft-log-to-file)[topshelfcraft/walk

A Craft-aware array\_walk() method, plus some super-convenient console commands, to easily call Craft service methods on a collection of elements or values.

221.5k](/packages/topshelfcraft-walk)

PHPackages © 2026

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