<p>I can't think of a different way to conditionally enable template caching (globally, i.e. not per <code>{% cache %}</code> tag) other than to conditionally set the <code>enableTemplateCaching</code> config setting to either <code>true</code> or <code>false</code>.</p>
<p>To your specific use case, I wouldn't worry about simply accessing the <code>$_GET</code> superglobal to look for that <code>nocache</code> param. This is essentially all that Craft itself does under the hood, when you use <code>Craft::$app-&gt;getRequest()-&gt;getQueryParams()</code> – except that Craft will also UTF8-encode and memoize the params, which shouldn't be critical.</p>
<p>So something like this should work fine:</p>
<pre class="lang-php prettyprint-override"><code>use craft\helpers\App;

$disableTemplateCaching = App::parseBooleanEnv($_GET['nocache']);

return [
    '*' =&gt; [
         'enableTemplateCaching' = !$disableTemplateCaching,
    ],
];
</code></pre>
<p>Another option is to set the config setting a bit later in the request lifecycle. For that, you can't use <code>config/general.php</code>, but will need to <a href="https://craftcms.com/docs/3.x/extend/module-guide.html" rel="nofollow noreferrer">create a custom module</a>, adding the relevant logic within an appropriate <a href="https://craftcms.com/docs/3.x/extend/events.html" rel="nofollow noreferrer">event</a> listener (setting/overriding the config setting can be done by accessing the <a href="https://docs.craftcms.com/api/v3/craft-services-config.html" rel="nofollow noreferrer">Config service</a>).</p>
<p>Using the <code>craft\web\Application::EVENT_INIT</code> event seems to work nicely; the below would go into your module's <code>init()</code> method:</p>
<pre class="lang-php prettyprint-override"><code>use Craft;
use craft\helpers\App;
use craft\web\Application;
use yii\base\Event;

Event::on(
    Application::class,
    Application::EVENT_INIT,
    static function (Event $event) {
    
        // Get the &quot;nocache&quot; query param value
        $noCacheParamValue = Craft::$app-&gt;getRequest()-&gt;getQueryParam('nocache');
    
        // Make sure it's a boolean
        $disableTemplateCaching = App::parseBooleanEnv($noCacheParamValue);
    
        // Set the enableTemplateCaching config setting using the Config service
        Craft::$app-&gt;getConfig()-&gt;getGeneral()-&gt;enableTemplateCaching = !$disableTemplateCaching;
    
    }
);
</code></pre>

CC BY-SA 4.0
2022-03-14T09:50:33.843Z
Thanks for the thoughtful response! You're right, the first approach should be alright, and using `$_GET` is indeed a bit simpler than `$_SERVER`. Though the second approach is even better, changing the config value on `init` is a great idea! Might lead to some head-scratching for other developers though, so for this approach I'll want to stick a comment in `general.php` explaining that the value might be changed by the module.
MoritzLost
CC BY-SA 4.0
2022-03-14T09:34:18.930Z
2022-03-14T11:11:26.387Z
2022-03-14T11:11:26.387Z
Mats Mikkel Rummelhoff
<p>I'm looking for a way to disable the template cache (<code>{% cache %}</code> tags) for the entire request based on a specific condition (not just based on the current environment). In this case, the condition is a query parameter (something like <code>?nocache=1</code>), but I'm also looking for a general solution to this. There is, of course, the <a href="https://craftcms.com/docs/3.x/config/config-settings.html#enabletemplatecaching" rel="nofollow noreferrer"><code>enableTemplateCaching</code> general config setting</a>, which I could use to toggle the template cache on and off:</p>
<pre class="lang-php prettyprint-override"><code>// config/general.php

$someCondition = true;

return [
    '*' =&gt; [
         'enableTemplateCaching' = $someCondition,
    ],
];
</code></pre>
<p>The problem is that the config is included super early during the request lifecycle, before the <code>Craft::$app</code> object is even constructed. So I can't use <code>Craft::$app-&gt;request-&gt;getQueryParam('nocache')</code> or anything else from the API. For query parameters specifically, I <em>could</em> access <code>$_SERVER['REQUEST_URI']</code> directly, but that feels kind of dirty. And it doesn't solve the problem if I need access to anything from the API to determine whether to enable caching or not.</p>
<p>I've checked if there's a hook in the <code>TemplateCaches</code> service I could use, but it doesn't look like it. The other solution would be to include the condition in every <code>{% cache %}</code> tag manually, but that's error-prone and noisy.</p>
<p>Is there a more general solution to turning off <code>{% cache %}</code> tags based on a specific condition for the current request?</p>

<templating><cache><request>
Disable template cache globally based on condition
# Disable template cache globally based on condition

(Asked by: username_0 on 2022-03-09)

I'm looking for a way to disable the template cache ({% cache %} tags) for the entire request based on a specific condition (not just based on the current environment). In this case, the condition is a query parameter (something like ?nocache=1), but I'm also looking for a general solution to this. There is, of course, the enableTemplateCaching general config setting, which I could use to toggle the template cache on and off:
// config/general.php

$someCondition = true;

return [
    '*' => [
         'enableTemplateCaching' = $someCondition,
    ],
];

The problem is that the config is included super early during the request lifecycle, before the Craft::$app object is even constructed. So I can't use Craft::$app->request->getQueryParam('nocache') or anything else from the API. For query parameters specifically, I could access $_SERVER['REQUEST_URI'] directly, but that feels kind of dirty. And it doesn't solve the problem if I need access to anything from the API to determine whether to enable caching or not.
I've checked if there's a hook in the TemplateCaches service I could use, but it doesn't look like it. The other solution would be to include the condition in every {% cache %} tag manually, but that's error-prone and noisy.
Is there a more general solution to turning off {% cache %} tags based on a specific condition for the current request?

**Tags:** templating, cache, request


---

## 1 answers

### Answer by username_1 on 2022-03-14. Score: 2 | Accepted answer

I can't think of a different way to conditionally enable template caching (globally, i.e. not per {% cache %} tag) other than to conditionally set the enableTemplateCaching config setting to either true or false.
To your specific use case, I wouldn't worry about simply accessing the $_GET superglobal to look for that nocache param. This is essentially all that Craft itself does under the hood, when you use Craft::$app->getRequest()->getQueryParams() – except that Craft will also UTF8-encode and memoize the params, which shouldn't be critical.
So something like this should work fine:
use craft\helpers\App;

$disableTemplateCaching = App::parseBooleanEnv($_GET['nocache']);

return [
    '*' => [
         'enableTemplateCaching' = !$disableTemplateCaching,
    ],
];

Another option is to set the config setting a bit later in the request lifecycle. For that, you can't use config/general.php, but will need to create a custom module, adding the relevant logic within an appropriate event listener (setting/overriding the config setting can be done by accessing the Config service).
Using the craft\web\Application::EVENT_INIT event seems to work nicely; the below would go into your module's init() method:
use Craft;
use craft\helpers\App;
use craft\web\Application;
use yii\base\Event;

Event::on(
    Application::class,
    Application::EVENT_INIT,
    static function (Event $event) {
    
        // Get the "nocache" query param value
        $noCacheParamValue = Craft::$app->getRequest()->getQueryParam('nocache');
    
        // Make sure it's a boolean
        $disableTemplateCaching = App::parseBooleanEnv($noCacheParamValue);
    
        // Set the enableTemplateCaching config setting using the Config service
        Craft::$app->getConfig()->getGeneral()->enableTemplateCaching = !$disableTemplateCaching;
    
    }
);

> **Comments:**
> **username_0**: Thanks for the thoughtful response! You're right, the first approach should be alright, and using `$_GET` is indeed a bit simpler than `$_SERVER`. Though the second approach is even better, changing the config value on `init` is a great idea! Might lead to some head-scratching for other developers though, so for this approach I'll want to stick a comment in `general.php` explaining that the value might be changed by the module.  

---

